如何在Ruby中的同一行上grep多个字符串

时间:2016-10-17 15:07:36

标签: ruby regex

如何修改我的if语句以grep同一行中的多个字符串?

string = "1.1.1.1 example.com"
if File.readlines("/etc/hosts").grep(/#{string}/).any?
    exit
else
    File.open("/etc/hosts", "w") { |file| file.write(host_file)}
end

这是它在bash中的工作原理:

if grep -q "1.1.1.1 example.com";
  then
      exit
else
    echo "1.1.1.1 example.com" >> /etc/hosts
fi

3 个答案:

答案 0 :(得分:1)

我个人建议使用Resolv::Hosts而不是手动解析hosts文件。由于它内置于库中,它将比你自己提出的任何东西都更好地处理边缘情况。

首先是location of the hosts file on different systems,然后继续使用1.1.1.1 example2.com example.com这样的条目,这些条目可以使用但不匹配你的grep表达式。

答案 1 :(得分:0)

从“How to read lines of a file in Ruby”看,我认为你需要使用:

File.readlines('foo').each do |line|

为了读取文件中的所有行,然后在每一行上执行grep。

答案 2 :(得分:0)

它并不完全清楚你要问的是什么,但从上下文看起来你想要一个可以用来搜索数组中多个条目的模式,因为readlines返回包含文件行的数组。

一个简单的模式示例是:

%w[foo bar baz].grep(/foo|bar/) # => ["foo", "bar"]

|表示"或",因此模式/foo|bar/正在寻找"foo" or "bar"grep将迭代数组['foo', 'bar'],并找到两者。

这不是整个解决方案,因为有龙在树林里等待。 /foo|bar/实际上匹配子字符串,而不是完整的单词:

%w[food bartender].grep(/foo|bar/) # => ["food", "bartender"]

很可能你想要的东西。

要解决此问题,我们必须告诉正则表达式引擎只找到单词:

%w[foo bar baz].grep(/\bfoo\b|\bbar\b/) # => ["foo", "bar"]
%w[food bartender].grep(/\bfoo\b|\bbar\b/) # => []

\b表示"字边界"这是非单词字符和单词字符之间的过渡。 \w是使用的模式,它在the Regexp documentation中定义。我强烈建议您阅读,因为您可能遇到其他潜在问题。出于我们的目的,\b并且默认行为可能很好。

虽然这个小模式有很多重复,正则表达式让我们可以删除复制:

%w[foo bar baz].grep(/\b(foo|bar)\b/) # => ["foo", "bar"]
%w[food bartender].grep(/\b(foo|bar)\b/) # => []

将括号组foo|bar用于捕获组,因此周围的\b将应用于括号内的任何内容,从而降低噪音。

有时候你不想实际捕获字符串,你只想匹配它。如果是这样的话,请阅读文档中关于非捕获组的内容。