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?
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.
Ruby possède une méthode pour cela:
File.readlines('foo').each do |line|
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 .
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.
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
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.
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