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
如何统计一个词在一行中出现了多少次? 例如,我有单词 "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