字符串的 Grep 命令不仅仅在未注释的行中存在

字符串的 Grep 命令不仅仅在未注释的行中存在
try2:
   set -vn
   set -o pipefail
   set -e
   if grep -v '^#' file.tx | grep -P 'name' file.tx; then \
      echo "    No name"; exit 0;\
      echo " This message is print from file.tx" \
      cat file.tx; fi

1)上面的代码尝试 grep if姓名不存在于文件.tx然后,它会回显“ 无名 ”。我只想 grep 这个词,如果它不存在于未注释的行中,但它似乎不起作用。

2)如果第一个陈述是假的,我想如何做,它将转到第二个陈述。上面的命令似乎不起作用。

注:这段代码写在Makefile中,目标名称为尝试2

答案1

如果我理解这个问题,你有一个像这样的文件:

# 带有神奇单词名称的评论

一些不包含魔法词的东西

并且您希望打印“No name”。如果第一行未注释,则不应打印“No name”。

以下应该做到这一点:

if grep -v '^#' file.tx | grep -q name; then
       echo "no name"
fi

在您的代码中,第二个grep包含文件名,因此它不会查看第一个的管道输入。另外,由于您没有使用 Perl 正则表达式,因此我删除了-P, 并且还添加了-q抑制任何grep匹配时可能打印的输出。

答案2

问题是,您不是name在 中的非注释数据中进行 grep 查找,而是针对原始文件运行file.txgrep

grep -v '^#' file.tx | grep -P 'name' file.tx
                                      ^^^^^^^
                                     will not read from pipe

相反,使用

grep -v '^#' file.tx | grep -q 'name'

即,不要使grep管道中的第二个文件从原始文件中读取。另外,由于您只对grep(在语句中使用)的退出状态感兴趣if,因此请将其与 一起使用-q


考虑到你的第二个问题,如果我理解正确的话,你似乎只想cat file.tx在字符串name出现在注释之外时才运行。在这种情况下,你的逻辑就倒退了。

if grep -v '^#' file.ex | grep -q 'name'; then

name如果字符串出现在非注释行中,则为 true 。如果您想要cat该文件,那么您需要在此处执行此操作:

if grep -v '^#' file.ex | grep -q 'name'; then \
    cat file.tx; \
else \
    echo 'No name'; \
fi

我不确定exit 0as 这对 Makefile 目标的其余部分有影响。如果你想让目标失败如果name不存在,则exit 1在 后执行echo,否则根本不退出(除非您不想在同一个 Makefile 目标中执行更多 shell 代码)。

我也注意到你的cd ../...除非file.tx当前目录中有在目录中../..cat您将失败。您没有提到为什么要向上两级目录,所以我不能对此多说。

另请注意,cd一旦 shell 片段完成,就会“撤消”,因为make在单独的 shell 实例中运行目标的每个单独行。这也意味着set您所拥有的各种指令都在运行分离贝壳。

相关内容