![计算每行文本出现的次数](https://linux22.com/image/87267/%E8%AE%A1%E7%AE%97%E6%AF%8F%E8%A1%8C%E6%96%87%E6%9C%AC%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AC%A1%E6%95%B0.png)
我必须解析巨大的文本文件,其中某些行令人感兴趣,而其他行则不感兴趣。在那些感兴趣的内容中,我必须计算某个关键字的出现次数。
假设该文件被调用input.txt
并且看起来像这样:
format300,format250,format300
format250,ignore,format160,format300,format300
format250,format250,format300
我想排除 的行ignore
并计算 的数量format300
,我该怎么做?
到目前为止,我得到的是这个命令,它每行只计算一次(这还不够好):
cat input.txt | grep -v ignore | grep 'format300' | wc -l
有什么建议么?如果可能的话我想避免使用 perl。
答案1
这一行应该能够做你想做的事:
grep -v ignore input.txt | sed 's/format300/format300\n/g' | grep -c "format300"
基本上,您将每次出现的关键字替换为关键字本身和换行符,这实际上使您的输入流在任何给定行上仅具有关键字一次。然后grep -c
是计算其中包含您的关键字的行数。
答案2
你不需要第一个cat
,它被称为猫的无用使用(UUOC)。
此外,非常有用的是grep -o
,它只输出匹配的模式,每行一个。
然后,用 计数行数wc -l
。
grep -v ignore YOUR_FILE | grep -o format300 | wc -l
这将打印3
您的小样本。
答案3
输入文件可能包含部分匹配,这会使结果无效,例如:
1 format300,format250,format300
2 format250,ignore,format160,format300,format300
3 format250,format250,format300
4 format999,format300000,format999
5 format999,ignore_me_not,format300
您不想计数format300000
第 4 行或忽略第 5 行,因为ignore_me_not
包含子字符串ignore
。
这可以解决问题:
grep -v "\bignore\b" FILE |grep -o "\bformat300\b"|wc -l
正确的输出是
4
..因为第 2 行被忽略,第 5 行未被忽略,并且第 4 行不完全包含format300
.
如果将wc -l
零件放出来,您可以看到到底匹配的是什么:
答案4
Perl 方式:
perl -lne '$k+=(s/format300//g) unless /ignore/; }{ print $k' input.txt
会将s/format300//g
所有出现的 替换format300
为空,并返回替换次数。这是一种计算出现次数的简单方法。然后将数字添加到其中$k
,并且只有当该行不匹配时才会发生整个事情ignore
。这}{
是 perl 的简写,表示“读完文件后执行此操作,因此print $k
将打印找到的总数。