如何删除文本文件中的特定行?

How to delete specific lines in text file?

假设,我有一个包含以下文本的 input.txt 文件:

First line
Second line
Third line
Fourth line

我想删除,例如,第二行和第四行得到这个:

First line
Third line

到目前为止,我使用此代码只删除了第二行中的一个

require 'fileutils'

File.open('output.txt', 'w') do |out_file|
  File.foreach('input.txt') do |line|
     out_file.puts line unless line =~ /Second/
  end
end

FileUtils.mv('output.txt', 'input.txt')

在 Ruby 中删除文本文件中多行的正确方法是什么?

使用 File.readlines 获取输入文件中行的数组。

input_lines = File.readlines('input.txt')

然后 select 只有索引为偶数的那些。

output_lines = input_lines.select.with_index { |_, i| i.even? }

最后,将它们写入输出文件。

File.open('output.txt', 'w') do |f|
  output_lines.each do |line|
    f.write line
  end
end

在一般情况下,从文本文件中干净高效地删除行是 "difficult",但如果您可以稍微限制问题,则可以很简单。

以下是 SO 提出的一些类似问题:

  • How do I remove lines of data in the middle of a text file with Ruby
  • Deleting a specific line in a text file?
  • Deleting a line in a text file
  • Delete a line of information from a text file

还有很多其他的。

在您的情况下,如果您的输入文件相对较小,您可以轻松负担得起使用您正在使用的方法。真的,唯一需要更改以满足您的标准的是将您的输入文件循环和条件修改为:

File.open('output.txt', 'w') do |out_file|
  File.foreach('input.txt').with_index do |line,line_number|
     out_file.puts line if line_number.even?  # <== line numbers start at 0
  end
end

变化是捕获行号,使用with_index方法,由于调用时File#foreach returns和Enumerator可以使用没有障碍;该块现在应用于 with_index,并获得行号作为第二个块参数。只需在比较中使用行号即可获得指定的标准。

这种方法可以扩展,即使对于有些大的文件也是如此,而将整个文件读入内存的解决方案对文件大小的上限相当低。使用此解决方案,您将受到可用磁盘 space 和 read/write 文件速度的更多限制;例如,对 space 有限的在线存储执行此操作可能无法如您所愿。写入本地磁盘或拇指驱动器,假设您有 space 可用,应该完全没有问题。