从ruby上的文件中删除文本行

时间:2013-06-08 18:59:36

标签: ruby

我有一个txt文件,每行都有一系列字符串。我需要找到一个给定的字符串,将该字符串移动到另一个文件并从该文件中删除该行。

移动到另一个文件正在运行,这是代码。

File.open('file_moved.txt', 'w') { |file| file.puts pick_random_line.to_i.to_s }

def pick_random_line
  chosen_line = nil
  File.foreach("file.txt").each_with_index do |line, number|
  chosen_line = line if rand < 1.0/(number+1)
  end
  chosen_line
end

我对如何从其他文件中删除该行感到有些迷茫。 Ruby中用匹配字符串删除整行的方法是什么?

2 个答案:

答案 0 :(得分:4)

这样的事情怎么样?

lines = File.readlines('file.txt')

random_line = lines.shuffle.pop

File.open('file.txt', 'w') do |f|
  f.write(lines.join(''))
end

File.open('random.txt', 'a') do |f|
  f.write(random_line)
end

请注意readlines具有将整个文件读入内存的效果,但这也意味着您可以从文件中获得真正的随机样本。您的实现可能更偏向于文件的末尾,因为您事先不知道有多少行。

与以这种方式进行操作的任何内容一样,如果此程序意外停止,则文件可能会被截断的可能性很小。避免这种情况的常用方法是写入临时文件,然后在成功时重命名。更好的选择是使用数据库,甚至是像SQLite这样的嵌入式数据库。

答案 1 :(得分:3)

从文件中删除任何字节或子字符串本质上意味着您必须至少从该点开始重写该文件。某些专业文件系统可能存在,但事实并非如此,但大多数通用文件系统不允许廉价地从文件中间删除字节。您可能最接近“应用此更改:删除这些行”类型的控件是类似git的版本管理系统。

就你的问题而言,这真的只是哲学 - 如果你的输出必须是删除了行的另一个文本文件,那么你只需生成两个文件:

  • 提取数据的新文件

  • 已删除数据的已更改原始文件(写回原始文件顶部)

您可以选择如何处理原始文件:

  • 读取所有数据,调整内存并覆盖原始数据。这是最简单的,但不能扩展到大文件。

  • 逐行读取数据,立即将每一行写入临时更改的文件或新文件。在该过程结束时,删除原始旧文件,并将临时更改的文件移动到其位置。这有点复杂,但可以处理更大的文件。