20

在 bash 中,我想说“如果一个文件不包含 XYZ,那么”做一堆事情。将其转换为代码的最自然方法是:

if [ ! grep --quiet XYZ "$MyFile" ] ; then
   ... do things ...
fi

但当然,这不是有效的 Bash 语法。我可以使用反引号,但随后我将测试文件的输出。我能想到的两种选择是:

grep --quiet XYZ "$MyFile"
if [ $? -ne 0 ]; then
   ... do things ...
fi

grep --quiet XYZ "$MyFile" ||
   (  ... do things ...
   )

我更喜欢第二个,它更 Lispy 和 || 控制流在脚本语言中并不少见。我也可以看到第一个参数,虽然当这个人阅读第一行时,他们不知道你为什么要执行 grep,看起来你正在执行它是为了它的主要效果,而不仅仅是为了控制脚本中的分支。

是否有第三种更直接的方式使用if语句并具有grepin 条件?

4

3 回答 3

37

就在这里:

if grep --quiet .....
then
    # If grep finds something
fi

或者如果 grep 失败

if ! grep --quiet .....
then
    # If grep doesn't find something
fi
于 2013-08-19T16:26:41.060 回答
12

您不需要[ ]( test) 来检查命令的返回值。试试看嘛:

if ! grep --quiet XYZ "$MyFile" ; then
于 2013-08-19T16:27:24.763 回答
3

这是一个品味问题,因为显然有多种可行的解决方案。当我处理这样的问题时,我通常wc -l在 grep 之后应用以计算匹配的行数。然后你有一个整数,你可以在测试条件内评估。如果问题只是是否存在匹配(匹配行数无关紧要),那么应用wc可能是 OTT 并且评估grep' 的返回码似乎是最好的解决方案:

通常,如果找到选定的行,则退出状态为 0,否则为 1。但如果发生错误,则退出状态为 2,除非使用 -q 或 --quiet 或 --silent 选项并找到选定的行。但是请注意,对于 grep、cmp 和 diff 等程序,POSIX 仅要求在出错时退出状态大于 1;因此,为了可移植性,建议使用测试此一般条件的逻辑而不是与 2 严格相等。

于 2013-08-19T16:27:18.683 回答