如何将字符串插入文本文件

时间:2010-01-26 11:35:14

标签: ruby-on-rails ruby

我有一个配置文件,我要添加一个字符串,例如那样:

line1
line2
line3
line4

不应附加新字符串,而是将其写入文件中间的某处。因此,我在文件中寻找一个特定的位置(或字符串),当它找到时,我插入我的新字符串:

file = File.open(path,"r+")
while (!file.eof?)
  line = file.readline
  if (line.downcase.starts_with?("line1"))
    file.write("Some nice little sentence")
  end
end

问题是Ruby用新文本覆盖该位置的行,结果如下:

line1
Some nice little sentence
line3
line4

我想要的是“真正的”插入:

line1
Some nice little sentence
line2
line3
line4

如何实现这一目标?

5 个答案:

答案 0 :(得分:11)

如果它是一个小文件,我认为最简单的方法是:

  • 阅读完整文件。
  • 插入行。
  • 撰写新文件。

这就是幕后Rails does it的方式。

或者您可以逐行复制,然后使用mv覆盖原始内容,如下所示:

require 'fileutils'

tempfile=File.open("file.tmp", 'w')
f=File.new("file.txt")
f.each do |line|
  tempfile<<line
  if line.downcase=~/^line2/
    tempfile << "Some nice little sentence\n"
  end
end
f.close
tempfile.close

FileUtils.mv("file.tmp", "file.txt")

答案 1 :(得分:6)

def replace(filepath, regexp, *args, &block)
  content = File.read(filepath).gsub(regexp, *args, &block)
  File.open(filepath, 'wb') { |file| file.write(content) }
end


replace(my_file, /^line2/mi) { |match| "Some nice little sentence"}

line1
Some nice little sentence
line2
line3
line4

如果你想附加到现有的......

replace(my_file, /^line2/mi) do |match| 
  "#{match} Some nice little sentence"
end

line1
line2 Some nice little sentence
line2
line3
line4

答案 2 :(得分:3)

其他几个选项:

file = File.read(path).sub(/line2\n/, 'Some nice little sentence\n\1')
File.write(path, file)

file = File.readlines(path)
index = file.index("line2")
file.insert(index, "Some nice little sentence")
File.write(path, file)

答案 3 :(得分:0)

最简单的方法是读取内存中的整个文件,然后将第一部分写回文件,将插入的行写入文件,然后将剩余部分写回文件。当您将文件作为行数组读取时,这应该相对简单,但如果您的文件非常大,则可能会遇到问题,因为您必须使用此方法将整个文件读入内存。

或者,您可以找到要插入线的点,将该点后的行读入内存,在文件中找回该点,将新行写入文件,最后将剩余的行写入文件。如果文件的其余部分非常大,您将再次遇到问题,因为您必须将其全部读入内存。

第三种方法是将第一部分写入新文件,将插入的行写入新文件,将原始文件的剩余部分写入新文件,最后将旧文件替换为新文件。文件系统。这种方法允许您一次处理一行,这样您就可以处理不适合内存的文件。

文件写入的原因是因为文件就像一个固定大小的字节数组:当你向文件写一个字节时,你将覆盖一个现有的字节(我忽略了你附加到一个字节的情况)在这里提交)。因此,向文件中插入任何内容的唯一方法是首先将旧内容从旧位置读取并将其写入新位置,然后将其移动到新位置。之后,您可以将数据“插入”现在空置的区域。

答案 4 :(得分:0)

tty-file gem 具有用于此目的的 inject_into_file 方法。

安装 gem:

gem install tty-file

那么:

require 'tty-file'
TTY::File.inject_into_file("filename.rb", "Some nice little sentence", after: "line1\n")