在 Ruby 中,如何在文件中的另一行之后添加一行?

How do I add a line after another line in a file, in Ruby?

更新了描述以使其更加清晰。

假设我有一个文件,里面有这些行。

one
two
three
five

如何在 "three" 行之后添加 "four" 行,使我的文件现在看起来像这样?

one 
two
three
four
five

假设您想使用 FileEdit class 执行此操作。

Chef::Util::FileEdit.new('/path/to/file').insert_line_after_match(/three/, 'four')

AWK 解决方案

虽然您可以在 Ruby 中执行此操作,但在 AWK 中执行此操作实际上是微不足道的。例如:

# Use the line number to choose the insertion point.
$ awk 'NR == 4 {print "four"}; {print}' lines
one
two
three
four
five

# Use a regex to prepend your string to the matched line.
$ awk '/five/ {print "four"}; {print}' lines
one
two
three
four
five

这是一个内存解决方案。它查找完整的行而不是进行字符串正则表达式搜索...

def add_after_line_in_memory path, findline, newline
  lines = File.readlines(path)
  if i = lines.index(findline.to_s+$/)
    lines.insert(i+1, newline.to_s+$/) 
    File.open(path, 'wb') { |file| file.write(lines.join) }
  end
end

add_after_line_in_memory 'onetwothreefive.txt', 'three', 'four'

以下 Ruby 脚本应该可以很好地完成您想要的操作:

# insert_line.rb
#   run with command "ruby insert_line.rb myinputfile.txt", where you
#   replace "myinputfile.txt" with the actual name of your input file
$-i = ".orig"
ARGF.each do |line|
  puts line
  puts "four" if line =~ /^three$/
end

$-i = ".orig" 行使脚本显示为就地编辑命名的输入文件,并制作名称后附加“.orig”的备份副本。实际上,它从指定的文件中读取并将输出写入临时文件,并在成功时重命名原始输入文件(具有指定的后缀)和临时文件(具有原始名称)。

这个特定的实现在找到 "three" 行后写入 "four",但是更改匹配的模式、使其基于计数或将其写入某个已识别的行之前是微不足道的而不是之后。

这是在匹配后插入 2 个新行的示例 ruby 块:

ruby_block "insert_lines" do
  block do
    file = Chef::Util::FileEdit.new("/path/of/file")
    file.insert_line_after_match("three", "four")
    file.insert_line_after_match("four", "five")
    file.write_file
  end
end

insert_line_after_match 搜索 regex/string 并将在匹配后插入值。