当 grep 未获得匹配项时打印字符串

当 grep 未获得匹配项时打印字符串

假设我有两个文件,如下所示:

$ cat search_file.txt
This line contains kwd1.
This line contains kwd2.
This line contains no match.
This line contains no match.
This line contains kwd5.
$ cat search_kwd.sh
grep kwd1 search_file.txt
grep kwd2 search_file.txt
grep kwd3 search_file.txt
grep kwd4 search_file.txt
grep kwd5 search_file.txt

当我运行 search_kwd.sh 时,我得到:

$ sh search_kwd.sh
This line contains kwd1.
This line contains kwd2.
This line contains kwd5.

string每当 grep 找不到匹配项时我想打印 a 。输出如下:

$ sh search_kwd.sh
This line contains kwd1.
This line contains kwd2.
string
string
This line contains kwd5.

我该如何在 bash 中做到这一点?

答案1

grep当没有找到任何东西时,以非零代码退出。

man grep

通常,如果选择了一行,则退出状态为 0;如果没有选择行,则退出状态为 1;如果发生错误,则退出状态为 2。

所以你可以使用:

grep kwd3 search_file.txt || echo "string"

答案2

要扩展 @RoVo 的答案,您可以使用 for 循环来迭代所有查询:

for term in "kwd1" "kwd2" "kwd3" "kwd4" "kwd5"; do
    grep "$term" search_file.txt || echo "string"`
done

答案3

由于请求的输出似乎每行输入都有一行输出,如果匹配则仅复制该行,如果不匹配则替换该行,因此有比读取文件 5 次并打印更好的方法来做到这一点按照在 search_kwd.sh 文件而不是输入文件中找到的顺序列出行。

相反,您应该一次处理输入文件 1 行。有很多工具可以做到这一点。例如

#!/bin/sh
sed -e '/kwd1/{p;d}
        /kwd2/{p;d}
        /kwd3/{p;d}
        /kwd4/{p;d}
        /kwd5/{p;d}
        s/.*/string/' search_file.txt

它表示对于每个匹配的关键词打印出该行,然后丢弃它并移动到下一行。如果它遍历了所有关键字并且没有匹配,则将该行更改为字符串(然后隐式打印它)。

你可以使用awk这样的东西

 #!/bin/sh
 awk '{ if (/kwd1|kwd2|kwd3|kwd4|kwd5/) { print } else {print "string" }}' search+file.txt

你可以有一个纯 shell 实现

 #!/bin/sh
 while read -r line
 do
     case "$line" in
     (*"kwd1"*|*"kwd2"*|*"kwd3"*|*"kwd4"*|*"kwd5"*) printf '%s\n' "$line" ;;
     (*) printf '%s\n' "string" ;;
     esac
 done < search_file.txt

您也可以使用 perl、ruby、python。

相关内容