Это самый простой способ сделать это в чистом ruby, который также работает для больших файлов, поскольку он обрабатывает каждую строку за раз вместо чтения всего файла в память:
INFILE = "input.txt"
OUTFILE = "output.txt"
total_lines = File.foreach(INFILE).inject(0) { |c, _| c+1 }
desired_lines = total_lines - 4
# open output file for writing
File.open(OUTFILE, 'w') do |outfile|
# open input file for reading
File.foreach(INFILE).with_index do |line, index|
# stop after reaching the desired line number
break if index == desired_lines
# copy lines from infile to outfile
outfile << line
end
end
Однако это примерно вдвое медленнее, чем то, что вы разместили в 160-мегабайтном файле, который я создал. Вы можете сбрить около трети, используя wc
, чтобы получить общее количество строк, и используя чистые Ruby для остальных:
total_lines = `wc -l < #{INFILE}`.strip.to_i
# rest of the Ruby File code
Еще одно предостережение: у вашего CSV не должно быть собственных разрывов строк. в любом содержимом ячейки, в этом случае вам понадобится анализатор CSV, и вместо него можно будет использовать CSV.foreach(INFILE) do |row|
, но в моем ограниченном тестировании это немного медленнее, но вы упомянули выше, что ваши ячейки должны быть в порядке процессов по строке файла.
Тем не менее, то, что вы разместили с помощью wc
и dd
, намного быстрее, поэтому, возможно, вам следует продолжать использовать это.