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.tx
grep
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 0
as 这对 Makefile 目标的其余部分有影响。如果你想让目标失败如果name
不存在,则exit 1
在 后执行echo
,否则根本不退出(除非您不想在同一个 Makefile 目标中执行更多 shell 代码)。
我也注意到你的cd ../..
.除非file.tx
当前目录中有和在目录中../..
,cat
您将失败。您没有提到为什么要向上两级目录,所以我不能对此多说。
另请注意,cd
一旦 shell 片段完成,就会“撤消”,因为make
在单独的 shell 实例中运行目标的每个单独行。这也意味着set
您所拥有的各种指令都在运行分离贝壳。