如何将文件中的多行从特定行gsub到特定行

时间:2014-12-03 14:59:14

标签: ruby

我尝试在文件中使用gsub,如下所示:

def meth(*args, &blk)
  "non-replaced"
end

# "replaced string starting"
def meth(*args, &blk)
  "replaced"
end
# "replaced string ending"

def meth(*args, &blk)
  "non-replaced"
end

我的问题是:如何只用有效的方式替换中间的“meth”,我可以用愚蠢的方式来做,例如realines>线条[from..to]>然后是lines.join(“\ n”),它会浪费太多时间,我希望有一种有效的方式,比如本机方法。

2 个答案:

答案 0 :(得分:0)

我猜你想要这样的东西:

contents = IO.read(filename)
replaced = contents.gsub(/# "replaced string starting"\n(.*)# "replaced string ending"/m, replace_contents)
IO.write(output_filename, replaced)

IO.read将整个文件作为单个文本字符串读取,gsub(/.../m, replaced_contents)将两个注释中的块替换为您想要的块,并IO.write将其写回输出文件。

答案 1 :(得分:0)

您应该在文件中找到用于打开gsub处理的标记或地标,然后再将其关闭。使用File.foreach可以轻松地逐行读取文件,这非常快,并提供了执行所需操作所需的粒度。 (请参阅“Why is "slurping" a file not a good practice?”,了解为何通常应避免使用readdeadlines进行“诽谤”。)

Ruby拥有专为此目的而设计的..运算符(AKA“触发器),并且可以非常轻松地处理您枚举的某些块。请参阅”Why does a Flip-Flop operator include the second condition?“和“Ruby - Get file contents with in a separator in an array”关于如何使用它的想法。

基本思想是逐行读取文件,查找块标记和切换处理。像这个未经测试的代码之类的东西是它的一般大纲:

File.open('/path/to/some/new_file.txt', 'w') do |fo|
  File.foreach('/path/to/some/file.txt') do |li|
    if (li[/some_start_pattern/] .. li[/some_stop_pattern/])
      li.gsub!(/pattern_of_thing_to_change/, 'text to substitute')
    end
    fo.puts li
  end
end

通过这种方式,您可以轻松扩展您在文件中处理的块数,或者您要替换的内容。

返回.. AKA“触发器”。它是从Perl借来的运营商,它从AWK获得。它会记住第一个测试的状态,在..的左侧,当切换为true时,..会记住,并返回true,直到第二个测试返回true,此时.. 1}}再次开始返回false。一旦掌握了它,就可以快速获取要处理的文件块。