如何修改我的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
答案 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
将应用于括号内的任何内容,从而降低噪音。
有时候你不想实际捕获字符串,你只想匹配它。如果是这样的话,请阅读文档中关于非捕获组的内容。