使用 grep 计算出现的总数

使用 grep 计算出现的总数

grep -c对于查找某个字符串在文件中出现的次数很有用,但它只对每行的每次出现进行一次计数。如何计算每行多次出现的次数?

我正在寻找比以下更优雅的东西:

perl -e '$_ = <>; print scalar ( () = m/needle/g ), "\n"'

答案1

grep-o只会输出匹配项,忽略行;wc可以数一下:

grep -o 'needle' file | wc -l

这也将匹配“needles”或“multineedle”。

要仅匹配单个单词,请使用以下命令之一:

grep -ow 'needle' file | wc -l
grep -o '\bneedle\b' file | wc -l
grep -o '\<needle\>' file | wc -l

答案2

如果您有 GNU grep(总是在 Linux 和 Cygwin 上,偶尔在其他地方),您可以计算输出行数grep -o: grep -o needle | wc -l

对于 Perl,我发现以下几种方法比你的更优雅(即使它是固定的)。

perl -lne 'END {print $c} map ++$c, /needle/g'
perl -lne 'END {print $c} $c += s/needle//g'
perl -lne 'END {print $c} ++$c while /needle/g'

仅使用 POSIX 工具时,一种方法(如果可能)是将输入拆分为具有单个匹配项的行,然后再将其传递给 grep。例如,如果您要查找整个单词,请首先将每个非单词字符转换为换行符。

# equivalent to grep -ow 'needle' | wc -l
tr -c '[:alnum:]' '[\n*]' | grep -c '^needle$'

否则,没有标准命令来执行此特定的文本处理,因此您需要转向 sed(如果您是受虐狂)或 awk。

awk '{while (match($0, /set/)) {++c; $0=substr($0, RSTART+RLENGTH)}}
     END {print c}'
sed -n -e 's/set/\n&\n/g' -e 's/^/\n/' -e 's/$/\n/' \
       -e 's/\n[^\n]*\n/\n/g' -e 's/^\n//' -e 's/\n$//' \
       -e '/./p' | wc -l

这是一个使用sedand 的更简单的解决方案grep,它适用于字符串甚至常规正则表达式,但在一些带有锚定模式的极端情况下会失败(例如,它在 中找到两次出现的^needleor )。\bneedleneedleneedle

sed 's/needle/\n&\n/g' | grep -cx 'needle'

请注意,在上面的 sed 替换中,我\n指的是换行符。这在模式部分是标准的,但在替换文本中,为了可移植性,用反斜杠换行符替换\n

答案3

如果像我一样,您实际上想要“两者;每个恰好一次”,(这实际上是“任一;两次”)那么它很简单:

grep -E "thing1|thing2" -c

并检查输出2

这种方法的好处(如果恰好一次你想要的)是它很容易扩展。

答案4

我需要这样做,但对于多个搜索词。我希望将它们列在列中,并列出每个列的出现次数。

我的仅 bash、一行的解决方案如下:

grep -o -E 'borp|flarb' flarb.log  | sort | uniq -c
 910 borp
9090 flarb

相关内容