首页 > 解决方案 > Bash,将 grep 的结果相加

问题描述

在 bash 中,我想回显一些整数值,它是各种“grep | wc -l”组合的总和。

我努力了

echo $( (`grep string file.txt | wc-l`) + (`grep string2 file.txt | wc -l`))

我假设这些 grep 的返回只是 bash 可以识别的整数,但事实并非如此。我在哪里需要明确,为什么?

标签: bashshellgrep

解决方案


简化您的内部命令(使用seq产生行)但保持相同的括号,这不起作用:

$ echo $( (`seq 5 | wc -l`) + (`seq 10 | wc -l`))
-bash: command substitution: line 1: syntax error near unexpected token `+'
-bash: command substitution: line 1: ` (`seq 5 | wc -l`) + (`seq 10 | wc -l`)'

Bash 中的算术扩展是两个相邻的括号:

$ echo $(( 1+2 ))
3

这有效:

$ echo $((`seq 5 | wc -l` + `seq 10 | wc -l`))
15

与更现代的版本一样:

$ echo $(( $(seq 5 | wc -l) + $(seq 10 | wc -l) ))
15

所以你的括号不匹配并且间距不正确。


作为旁注,如果您可以重构两者grep以产生一个输出,例如:

$ grep "string 1|string2" | wc -l

正如 Charles Duffy 建议的那样,通过在子 shell 或同一个 shell 中进行命令分组,您可以将两个 greps 输出组合在一个流中。那么你不需要echoor 算术。

作为来自两个不同流程的生产线的简单模型seq,您可以执行以下操作:

$ (seq 10; seq 5) | wc -l     # sub shell
      15
$ { seq 5; seq 10; } | wc -l  # same shell
      15

最后,在某种程度上,你有“各种”grep | 的总和。wc -l" 组合" 您可能会认为awk是更好的grep+wc替换。

你可以做:

awk '/string1/{c++} /string2/{c++} END{print c+0}' file.txt

以及比您单独在 Bash 中应该做的更复杂的组合。如果您有许多不同的搜索字符串,它将执行得更好。


推荐阅读