我有一个自定义日志文件的输出,如下所示:
8 24 yum
8 24 yum
8 24 make
8 24 make
8 24 cd
8 24 cd
8 25 make
8 25 make
8 25 make
8 26 yum
8 26 yum
8 26 make
8 27 yum
8 27 install
8 28 ./linux
8 28 yum
我想知道是否有办法计算第三个字段的特定值的数量。例如,我可能想计算cd
,yum
且install
仅的数量。
完成这项工作的经典 shell 脚本是:
awk '{print $3}' "$file" | sort | uniq -c | sort -n
用 提取第 3 列的值awk
,将相同的名称排序在一起,计算重复次数,按计数升序对输出进行排序。这sort | uniq -c | sort -n
部分是一个常见的模因。
如果您使用的是 GNU awk
,您可以在awk
脚本中完成所有操作;它可能更有效,但对于真正庞大的文件,它可能会在管道没有的地方耗尽内存(sort
必要时溢出到磁盘;编写代码以溢出到磁盘awk
是不明智的)。
您可以使用awk
来获取第三个字段值并wc -l
计算数量。
awk '$3=="cd"||$3=="yum"||$3=="install"||$3=="cat" {print $0}' file | wc -l
您也可以使用egrep
,但这不仅会在第三个字段中查找这些词,还会在该行的其他任何地方查找这些词。
egrep "(cd|yum|install|cat)" file | wc -l
如果您想计算第三个字段上的特定单词,那么您可以在没有多个正则表达式的情况下执行上述操作。
awk '$3=="cd" {print $0}' | wc -l
使用cut
,sort
和uniq
:
$ cut -d" " -f3 inputfile | sort | uniq -c
2 cd
1 install
1 ./linux
6 make
6 yum
用于awk
计算字段三的出现次数sort
并对输出进行排序:
$ awk '{a[$3]++}END{for(k in a)print a[k],k}' file | sort -n
1 install
1 ./linux
2 cd
6 make
6 yum
所以按命令过滤:
$ awk '/cd|yum|install/{a[$3]++}END{for(k in a)print a[k],k}' file | sort -n
1 install
2 cd
6 yum
grep
要停止部分匹配,例如egrep
使用单词边界\<
等\>
,过滤器将是/\<cd\>|\<yum\>|\<install\>/
对于您的输入
awk '{++a[$3]}END{for(i in a)print i "\t" a[i];}' file
将打印:
cd 2
install 1
./linux 1
make 6
yum 6
您可以使用grep
同时过滤多个术语:
cut -f3 -d' ' file | grep -x -e yum -e make -e install | sort | uniq -c
解释:
-x
标志仅匹配完全匹配的行,就像使用^pattern$
cut
仅提取第 3列sort
在从输入中删除所有垃圾之后,我们uniq
最终计数以提高效率我想你想分别计算yum
install
&的值cd
。如果是这样,您应该选择 3 个单独的 awk 语句:awk '$3=="cd" {print $0}' file | wc -l
awk '$3=="yum" {print $0}' file | wc -l
awk '$3=="install" {print $0}' file | wc -l