如何更新文本文件中的单个匹配行?

时间:2012-07-14 22:05:14

标签: ruby regex file-io

我正在尝试编写一个脚本,将一些数据块存储在平面.txt文件中(它们是小文件,少于100行)

无论如何,我试图实际上用一个新的值更新一行匹配行,同时将其他所有内容留在文件中,但不能完全弄清楚如何修改1行而不是更换完整行文件。

到目前为止,这是我的代码:

# get file contents as array.
array_of_lines = File.open( "textfile.txt", "r" ).readlines.map( &:chomp )

line_start = "123456:"    # unique identifier
new_string = "somestring" # a new string to be put after the line_start indentifier.

# cycle through array finding the one to be updated/replaced with a new line.
# the line we're looking for is in format 123456:some old value

# delete the line matching the line_start key
array_of_lines.delete_if( |line| line_start =~ line )

# write new string into the array.
array_of_lines.push( "#{line_start}:#{new_string}" )

# write array contents back to file, replacing all previous content in the process
File.open( "textfile.txt", "w" ) do |f|
    array_of_lines.each do |line|
        f.puts line
    end
end

textfile.txt内容将始终由以下格式组成:

  

UNIQUE_ID:string_of_text

我可以使用脚本生成的应用数据来匹配unique_id,以确定要更新的文本行。

有没有更好的方法来做我想做的事情?

将整个文件读入内存似乎有点低效,只需更新该文件中的一行就可以循环所有内容。

1 个答案:

答案 0 :(得分:4)

除非您编写的新数据与旧数据的长度相同,否则您无法执行所需操作。

如果长度不同,则需要移动修改后文件中的所有字节。移动文件数据总是涉及重写所有内容(从修改开始)。在这种情况下,你也可以重写整个文件,因为你的文件很小。

如果替换数据的长度相同,则可以使用IO.seek将文件指针放到适当的位置,然后使用write输入替换数据。

如果你仍然不想重写整个文件,而只是移动数据(如果替换长度不同),那么你需要seek到正确的位置然后{{1}从那一点开始,一切都到了文件的末尾。如果替换时间较短,您还需要调用File.truncate来调整文件大小。