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

标签 ruby regex file-io

我正在尝试编写一个脚本,将一些数据 block 存储在平面 .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 以确定要更新哪一行文本。

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

将整个文件读入内存似乎有点低效,遍历所有内容只是为了更新该文件中的一行。

最佳答案

除非您正在写入的新数据与旧数据的长度相同,否则您无法为所欲为。

如果长度不同,则修改后文件中的所有字节都需要移动。移动文件数据总是涉及重写所有内容(从修改点开始)。在那种情况下,您还不如重写整个文件,因为您的文件太小了。

如果替换数据长度相同,那么可以使用IO.seek将文件指针指向适当的位置,然后只需使用 write 即可输入替换数据。

如果您仍然不想重写整个文件,而只是移动数据(如果替换长度不同),那么您需要寻找到正确的位置然后write 从那一点开始,所有内容都到文件末尾。如果更换的更短,您还需要调用 File.truncate调整文件大小。

关于ruby - 如何更新文本文件中的单个匹配行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11487715/

相关文章:

json - 在 Ruby 中将 JSON 转换为 hashmap

asp.net - 从正则表达式中排除 <br> 标记而不是从文本中删除?

regex - 整个字符串与/.*/之后的第二个匹配是什么?

ruby - f.gets.chomp 在做什么? (艰难地学习 Ruby : Exercise 20)

Python:相互依赖的进程/线程队列

c# - Servlet,写入数据

ruby-on-rails - Rails curl 语法

ruby-on-rails - Rails yield 和 content_for 部分

ruby - Net::HTTP 中的服务器名称指示支持?

c# - 在 C# 中使用正则表达式返回包含匹配项的整行