Shell 编程如何统计一个单词在一行中出现了多少次?

Shell Programming How to count how many times a word appears in a line?

如何统计一个词在一行中出现了多少次? 例如,我有单词 "man" 和以下几行:

a man walks here
nobody over here
from man to man

结果应该是:第一行一次,第二行0次,最后一行两次。

使用 awk 可以轻松做到这一点:

awk -F 'man' '{print (NF?NF-1:0)}' file

1
0
2

-F 'man' 将输入字段分隔符设置为 man 并且 NF 打印每行的字段数。

如果您想计算完整的单词,请使用此 gnu-awk:

awk -F '\<man\>' '{print (NF?NF-1:0)}' file

对于非 gnu awk,你可以使用这个:

awk -F '(^|[^[:alnum:]])man([^[:alnum:]]|$)' '{print (NF?NF-1:0)}' file

如果您不想计算 mankind 或其他包含 man 的字符串,您可以在空格处中断并循环遍历每个字段:

$ awk '{c=0; for(i=1;i<=NF;i++) if ($i~/^man$/) c++; print c}' file

如果要使用变量:

$ awk -v m=man '{c=0; for(i=1;i<=NF;i++) if ($i==m) c++; print c FS m}' file

如果你有 gawk vs POSIX awk,你可以这样做:

$ awk '{n=gsub(/\<man\>/, ""); print n}' file
$ cat file
a man walks here
nobody over here

from man to man

$ awk -v tgt="man" '{print gsub("(^|[[:space:]])"tgt"([[:space:]]|$)","&")}' file
1
0
0
2

以上内容在任何 awk 中都有效,它只依赖于 space 分隔的单词。

当您想查看行号并跳过没有出现的行时,您可以尝试类似

grep -no man file | uniq -c | cut -d":" -f1 | xargs printf "%d occurances in line %s\n"

试试这个版本:它支持多文件搜索,生成的输出看起来像 grep -nH:

#!/usr/bin/awk -f
BEGIN {
  word=ARGV[1];
  ARGV[1]="";
  print "Filename:Line #:" word " #:source line";
}
{
  count=0;
  for (i=1; i<=NF; i++) {
    if ($i == word) {
      count++;
    }
  }
  print FILENAME ":" FNR ":" count ":" [=10=];
}

测试:

$ ls
file  speach.txt  wordgrep.awk

$ cat file
a man walks here
nobody over here
from man to man

$ cat speach.txt
An old man is equal to any other man
Petrol is not good for life

$ ./wordgrep.awk man file speach.txt
Filename:Line #:man #:source line
file:1:1:a man walks here
file:2:0:nobody over here
file:3:2:from man to man
speach.txt:1:2:An old man is equal to any other man
speach.txt:2:0:Petrol is not good for life