计算一行中出现的第一个字母,并使用grep在shell/linux中显示摘要
我有一个像这样的日志计算一行中出现的第一个字母,并使用grep在shell/linux中显示摘要,shell,grep,Shell,Grep,我有一个像这样的日志 I:5000:GAME I:5000:GAME I-:5000:GAME I-:5000:GAME E:5000:GAME E:5000:GAME E:5000:GAME E:5000:GAME E:5000:GAME J:5000:GAME J:5000:GAME J:5000:GAME L:5000:GAME M:5000:GAME K:5000:GAME 我想做的是计算以字母E,I-,J开头的行,然后按降序排序 样本输出 5 E 3 J 2 I- 这就是我想
I:5000:GAME
I:5000:GAME
I-:5000:GAME
I-:5000:GAME
E:5000:GAME
E:5000:GAME
E:5000:GAME
E:5000:GAME
E:5000:GAME
J:5000:GAME
J:5000:GAME
J:5000:GAME
L:5000:GAME
M:5000:GAME
K:5000:GAME
我想做的是计算以字母E,I-,J开头的行,然后按降序排序
样本输出
5 E
3 J
2 I-
这就是我想输入的内容
sort /home/prod-dev/progex_logs.txt | egrep '^E|^I|^J' | cut -f1 -d: | uniq -c
我的文件是progex|u logs.txt,但它没有显示我想要的答案 这将使用给定的模式执行扩展grep。结果将传递给wc命令,以计算从egrep生成的行数。尝试以下操作:
sort data | cut -f1 -d: | uniq -c
这将按词汇对输入数据进行排序,只提取第一列,然后将结果传递到uniq-c
,这将折叠重复的行并计算折叠的行数。给定示例输入,这将生成:
5 E
2 I-
2 I
3 J
1 K
1 L
1 M
如果只需要E、I和J,可以使用user2254435发布的egrep
命令过滤掉它们,如下所示:
sort data | egrep '^I-|^E|^J' | cut -f1 -d: | uniq -c
这会让你:
5 E
2 I-
3 J
那么这有什么用呢?
第一个命令:
sort data
生成按词汇排序的数据版本。根据你的样品
输入,我们得到:
E:5000:GAME
E:5000:GAME
E:5000:GAME
E:5000:GAME
E:5000:GAME
I-:5000:GAME
I-:5000:GAME
I:5000:GAME
I:5000:GAME
J:5000:GAME
J:5000:GAME
J:5000:GAME
K:5000:GAME
L:5000:GAME
M:5000:GAME
然后,我们使用
|
操作符,它允许我们从一个命令向另一个命令发送stdout
另一个命令的stdin。此命令作为输入读取输出
从sort
命令中,提取第一个(-f1
)
冒号分隔的字段(-d:
)。这给了我们:
E
E
E
E
E
I-
I-
I
I
J
J
J
K
L
M
5 E
然后,我们通过管道将输出传输到uniq-c
,这将折叠重复的行
并生成折叠了多少行的计数。因此,考虑到
输入如下:
E
E
E
E
E
运行uniq-c
可以为我们提供:
E
E
E
E
E
I-
I-
I
I
J
J
J
K
L
M
5 E
有关所有这些的更多信息,请参阅的手册页,
,和。您可以使用awk执行此操作
cat ip.txt | awk 'BEGIN{IC=0;JC=0;EC=0}{if(index($0,"I-")>0)IC++;else if(index($0,"E:")>0)EC++;else if(index($0,"J:")>0)JC++;}END{printf("I- %d\n",IC);printf("E: %d\n",EC);printf("J: %d\n",JC);}'
这是使用
awk
awk -F: '/^(E|I-|J)/ {a[$1]++} END {for (i in a) print i,a[i]}' file
I- 2
E 5
J 3
要对其进行排序,您可以执行以下操作:
awk -F: '/^(E|I-|J)/ {a[$1]++} END {for (i in a) print i,a[i]}' file | sort -rk2
E 5
J 3
I- 2
工作原理
awk -F: ' # setting field separator to :
/^(E|I-|J)/ { # run this section only if starting with E, I- or J
a[$1]++} # add field #1 to array a
END { # end section
for (i in a) # looping through all element in array
print i,a[i]} # print element name and the number of elements
' file | sort -rk2 # sort output by column #2 in reverse order
我不认为这会给他提供他想要的示例输出,这是具有相同初始字段的行数的汇总。你是对的。我应该更仔细地阅读这个问题。拉尔克斯爵士,这个代码做什么“| cut-f1-d:|”?如果你能解释一下,既然是初学者。谢谢我用一些解释性的注释更新了我的答案。这是我输入的,但它没有运行sort/home/prod dev/progex|u logs.txt | egrep'^E | ^I | ^J'| cut-f1-d:| uniq-cComments对这类事情并没有真正的好处。使用您运行的命令更新您的问题,以及(a)它产生了什么错误或(b)输出是什么样子的。如果输出中只需要
I-
而不需要I
,则需要修改egrep
命令:sort/home/prod dev/progex_logs.txt | egrep'^E | I-^J'| cut-f1-d:| uniq-c
如果确实需要反转字段,请将uniq-c
的输出管道连接到awk'{print$2,$1}。另外,请看我对Raghuram的回答的评论,其中显示了如何使用awk
完成整个过程。这是一个极其复杂的awk
命令。考虑<代码> AWK-F:'$ 1 ~/E.jj i/{ToTales [$ 1 ] ++}结束{ for(i in toTales)打印i,toTals[i] } 代码不复杂。逻辑是我有3个变量用于3个模式(每个模式一个)。根据图案增加计数器,并进行打印。你的想法也很好。就像你读了我对拉古拉姆答案的评论,然后把它变成了你自己的一样。@larsks我没有使用你的任何解决方案,我自己写了,所以给一个负号并不可怕。这只是使用awk
的一种正常方式,我现在先看看你的评论。