用新行替换文本文件中的行

时间:2016-04-16 20:13:04

标签: ruby file

我想用新行替换文件中的一行,例如:

文件:

test
test
test
testing
test

来源:

def remove_line(line)
  if line == line
    #remove line including whitespace
    File.open('test.txt', 'a+') { |s| s.puts('removed successfully') }
  end
end

因此预期的输出将是这样的:

remove_line('testing')
test
test
test
removed successfully
test

现在我做了一些研究,只能找到添加一个空白行,我想我可以通过它删除所有空行并只是附加到文件,但必须有一个更简单的方法来用另一个字符串替换一行?

3 个答案:

答案 0 :(得分:2)

首先,打开文件并保存实际内容。然后,替换字符串并将完整内容写回文件。

def remove_line(string)
  # save the content of the file
  file = File.read('test.txt')
  # replace (globally) the search string with the new string
  new_content = file.gsub(string, 'removed succesfully')
  # open the file again and write the new content to it
  File.open('test.txt', 'w') { |line| line.puts new_content }
end

或者,而不是全球替换:

def remove_line(string)
  file = File.read('test.txt')
  new_content = file.split("\n")
  new_content = new_content.map { |word| word == string ? 'removed succesfully' : word }.join("\n")
  File.open('test.txt', 'w') { |line| line.puts new_content }
end

答案 1 :(得分:0)

我找到了一个参考答案here它并不完全相同,因为它们正在搜索模式。

所以我会这样做:

def remove_line(line)
  file.open('test.txt', 'a+').each_line do |line|
    line.gsub('<line/to/replace>', '<new/line/here>')
  end
end

这应该将作为参数给出的那一行替换为你想要替换为的任何新行..

答案 2 :(得分:0)

给定此输入文件,存储为&#34; test.txt&#34;:

test
test
test
testing
test

以及此示例代码:

def remove_line(line_to_remove)
  File.foreach("test.txt").with_index do |line, line_num|
    line.gsub!(/[\r\n]+$/, '')
    if line == line_to_remove
      puts "removed successfully"
    else
      puts line
    end
  end
end

您可以成功运行:

remove_line('testing')

并获得此输出:

test
test
test
removed successfully
test

该函数获取要删除的行的内容,并在&#34;逐行&#34;中打开文件。时尚。这是惯用的Ruby,应该优先于&#34; slurping&#34;文件,如接受此SO question的答案中所述。

一旦我们有了一条线,就必须从它上面剥去线的结尾。由于我们不确切地知道将在哪个平台上运行(或者文本文件是在其上创建的),因此我们使用正则表达式来查找所有已知的行结束字符(&#39; \ r \ n&#39;是Windows,&#39; \ n&#39;是Linux / Unix / Mac OS X,&#39; \ r&#39;是Mac Classic)。

然后我们检查该行是否符合我们要删除的内容。如果匹配,我们会从输出中省略它,而是打印它已成功删除&#34 ;;否则,我们输出不匹配的行。

这符合原始设计意图,但是,要改进设计并使整体更有用的功能,还有很多工作要做。那么为什么不继续这样做呢?

首先,我们将该函数作为参数使用文件名。这将从"test.txt"调用中删除硬编码的foreach文件名。这将使这种变化发生:

def remove_line(filename, line_to_remove)
  File.foreach(filename).with_index do |line, line_num|
    line.gsub!(/[\r\n]+$/, '')
    if line == line_to_remove
      puts "removed successfully"
    else
      puts line
    end
  end
end

您可以通过这种方式成功运行它,它将产生完全相同的输出:

remove_line("test.txt", "testing")

接下来,让我们改变输出的方式,并且我们将使用一个块来执行此操作,因为这是Ruby Way。以下是输出块的函数:

def remove_line(filename, line_to_remove, &block)
  proc = block_given? ? block : lambda {|s| puts s }
  File.foreach(filename).with_index do |line, line_num|
    line.gsub!(/[\r\n]+$/, '')
    if line == line_to_remove
      proc.call "removed successfully"
    else
      proc.call line
    end
  end
end

这是使用可选的块参数构建的,因此您可以像以前的版本一样调用它以使其以完全相同的方式工作,或者您可以使用显式块调用它并执行一些很酷的操作。这个运行它的示例在调用puts之前稍微修改了字符串以打印行:

remove_line("test.txt", "testing") {|s| puts "#{s} in your pants" }

有了这种额外的幼稚,你得到这个输出:

test in your pants
test in your pants
test in your pants
removed successfully in your pants
test in your pants

你现在有能力做有趣的事情,从其他有趣的东西建立起来。明智地使用它并继续这样做Ruby Way。