Как читать и перезаписывать текстовый файл одновременно в Ruby - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь отфильтровать повторяющиеся строки в тексте.Я использовал ruby -i для редактирования на месте, но результат выводит только stdout.Поэтому я попытался написать от руки.

ARGV.each do |filename|
    File.open(filename, 'r+') do |file|
        ret = file.readlines.uniq.join()
        # file.rewind
        # file.truncate(???)
        # file.seek(0)
        # file.write ret
        file.puts ret
    end
end

Ни один из них не работает.Лучшее, что я могу получить - это содержимое, добавленное к файлу, которое просто создает больше дубликатов.

Пожалуйста, пощади меня.

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019
ARGV.each do |filename|
  new_content = File.readlines(filename).uniq(&:rstrip).join.rstrip
  File.write(filename, new_content)
end

Это считывает весь файл как отдельные строки, удаляет повторяющиеся строки (игнорируя символы новой строки), объединяет строки для создания содержимого нового файла в виде одной строки и удаляет пробелы с его конца.Наконец, мы записываем новое содержимое в файл, переопределяя существующее содержимое.

Обратите внимание, что новая версия файла не будет иметь символ новой строки в конце.Если вам нужен символ новой строки в конце файла, вы можете просто добавить его к new_content перед вызовом File::write.


Если вы хотите использовать тот же дескриптор для чтения и записи,затем сделайте что-то вроде этого:

ARGV.each do |filename|
  File.open(filename, 'r+') do |f|
    new_content = f.readlines.uniq(&:rstrip).join.rstrip  # Read the entire file as individual lines, removes duplicate lines (ignoring the new line character(s)), concatenate the lines to create new file's content as one string and remove white spaces from its end
    f.rewind                                              # Rewind to the beginning of the file
    f.write(new_content)                                  # Write new content to the file overriding existing content
    f.truncate(f.pos)                                     # Remove the file's content after the current position
  end
end

Хотя я не вижу реального преимущества этой версии перед первой.Код становится более запутанным, и мы вынуждены использовать File#truncate, который описывается как «Доступно не на всех платформах».

0 голосов
/ 28 февраля 2019

Сначала вы должны прочитать файл построчно, вставить в массив и сделать его уникальным.Затем выведите строки

ARGV.each do |filename|      
  text=File.open(filename).read
  text.gsub!(/\r\n?/, "\n")
  lines=[]
  text.each_line do |line|
    lines << line unless lines.include? line
  end
  File.open(filename, 'w+') do |f|
    f.puts(lines)
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...