Hoe regels van een bestand in Ruby te lezen

Ik probeerde de volgende code te gebruiken om regels uit een bestand te lezen. Maar bij het lezen van een bestandstaat de inhoud allemaal op één regel:

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

Maar dit bestanddrukt elke regel afzonderlijk af.


Ik moet stdin gebruiken, zoals ruby my_prog.rb < file.txt, waarbij ik niet kan aannemen wat het regeleindteken is dat het bestand gebruikt. Hoe kan ik ermee omgaan?


Antwoord 1, autoriteit 100%

Ik geloof dat mijn antwoord je nieuwe zorgen over het omgaan met elk type regeleinde dekt, aangezien zowel "\r\n"als "\r"zijn geconverteerd naar de Linux-standaard "\n"voordat de regels worden ontleden.

Om het "\r"EOL-teken samen met het gewone "\n"en "\r\n"van Windows, dit is wat ik zou doen:

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

Natuurlijk kan dit een slecht idee zijn bij zeer grote bestanden, omdat het betekent dat het hele bestand in het geheugen moet worden geladen.


Antwoord 2, autoriteit 95%

Ruby heeft hier wel een methode voor:

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

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


Antwoord 3, autoriteit 90%

File.foreach(filename).with_index do |line, line_num|
   puts "#{line_num}: #{line}"
end

Dit zal het gegeven blok voor elke regel in het bestand uitvoeren zonder het hele bestand in het geheugen te slurpen. Zie: IO::foreach.


Antwoord 4, autoriteit 12%

Je eerste bestand heeft Mac Classic-regeluitgangen (dat is "\r"in plaats van de gebruikelijke "\n"). Open het met

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

om de regeleindes op te geven.


Antwoord 5, autoriteit 6%

Ik ben voorstander van de volgende benadering voor bestanden met headers:

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

Hierdoor kunt u een kopregel (of regels) anders verwerken dan de inhoudsregels.


Antwoord 6, autoriteit 5%

Het komt door de eindlijnen in elke regel.
Gebruik de chomp-methode in ruby om de eindregel ‘\n’ of ‘r’ aan het einde te verwijderen.

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

Antwoord 7, autoriteit 4%

hoe zit het met gets?

myFile=File.open("paths_to_file","r")
while(line=myFile.gets)
 //do stuff with line
end

Antwoord 8, autoriteit 3%

Vergeet niet dat als u zich zorgen maakt over het lezen in een bestand dat enorme lijnen heeft die tijdens runtime uw RAM zou kunnen meenemen, u altijd het bestandsdeel maaltijd kunt lezen. Zie “Waarom een bestand slurpt is slecht “.

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

Other episodes