Comment lire les lignes d'un fichier en Ruby

j'ai essayé d'utiliser le code suivant pour lire les lignes d'un fichier. Mais en lisant un fichier , les contenus sont tous dans une ligne:

line_num=0
File.open('xxx.txt').each do |line|
  print "#{line_num += 1} #{line}"
end

Mais ce fichier imprime chaque ligne séparément.


- je utiliser l'entrée standard stdin, comme ruby my_prog.rb < file.txt , où je ne peux pas présumer de la ligne de fin de caractère, c'est que le fichier utilise. Comment puis-je gérer cela?

194
demandé sur the Tin Man 2011-05-16 07:29:34

8 réponses

je crois que ma réponse couvre vos nouvelles préoccupations concernant le traitement de n'importe quel type de fin de ligne puisque les deux "\r\n" et "\r" sont convertis en standard Linux "\n" avant d'analyser les lignes.

pour supporter le caractère "\r" de EOL avec le normal "\n" , et "\r\n" de Windows, voici ce que je ferais:

line_num=0
text=File.open('xxx.txt').read
text.gsub!(/\r\n?/, "\n")
text.each_line do |line|
  print "#{line_num += 1} #{line}"
end

bien sûr, cela pourrait être une mauvaise idée sur de très gros fichiers car cela signifie Charger tout le fichier dans la mémoire.

126
répondu Olivier L. 2016-10-17 17:52:05

Ruby possède une méthode pour cela:

File.readlines('foo').each do |line|

http://ruby-doc.org/core-1.9.3/IO.html#method-c-readlines

457
répondu Jonathan 2016-10-17 17:52:32
File.foreach(filename).with_index do |line, line_num|
   puts "#{line_num}: #{line}"
end

ceci exécutera le bloc donné pour chaque ligne dans le dossier sans slurping le dossier entier dans la mémoire. Voir: IO:: foreach .

304
répondu talabes 2016-10-17 23:14:41

votre premier fichier a des terminaisons de ligne Mac Classic (c'est "\r" au lieu de l'habituel "\n" ). Ouvre avec

File.open('foo').each(sep="\r") do |line|

pour préciser les fins de ligne.

16
répondu Josh Lee 2011-05-16 03:36:18

c'est à cause des lignes terminales dans chaque ligne. Utilisez la méthode chomp dans ruby pour supprimer l'endline '\n' ou 'r' à la fin.

line_num=0
File.open('xxx.txt').each do |line|
  print "#{line_num += 1} #{line.chomp}"
end
5
répondu Sreenivasan AC 2014-06-30 05:45:20

je suis en faveur de l'approche suivante pour les fichiers qui ont des en-têtes:

File.open(file, "r") do |fh|
    header = fh.readline
    # Process the header
    while(line = fh.gets) != nil
        #do stuff
    end
end

cela vous permet de traiter une ligne d'en-tête (ou des lignes) différemment des lignes de contenu.

5
répondu Ron Gejman 2014-06-30 16:55:31

et obtient ?

myFile=File.open("paths_to_file","r")
while(line=myFile.gets)
 //do stuff with line
end
5
répondu JBoy 2014-08-19 19:47:18

n'oubliez pas que si vous êtes soucieux de lire dans un fichier qui pourrait avoir d'énormes lignes qui pourraient inonder votre RAM pendant l'exécution, vous pouvez toujours lire le morceau de fichier-repas. Voir " Pourquoi aspirer un fichier qui est mauvais ".

File.open('file_path', 'rb') do |io|
  while chunk = io.read(16 * 1024) do
    something_with_the chunk
    # like stream it across a network
    # or write it to another file:
    # other_io.write chunk
  end
end
4
répondu Nels 2017-05-23 12:18:27