我有Apache日志文件,access.log,如何计算该文件中出现的行数?例如cut -f 7 -d ' ' | cut -d '?' -f 1 | tr '[:upper:]' '[:lower:]'的结果是

a.php
b.php
a.php
c.php
d.php
b.php
a.php


我想要的结果是:

3 a.php
2 b.php
1 d.php # order doesn't matter
1 c.php 


评论

|排序uniq -c

| LC_ALL = C排序| LC_ALL = C uniq -c

啊,我不知道uniq可以做到。.

您是否在日志中有该行的示例,因为我认为可以使用awk来完成所有操作,而无需所有管道。

没关系,在大约2分钟内处理了8.1GB日志文件,并且现在已经完成,不再需要此文件:3

#1 楼

| sort | uniq -c


如注释中所述。

将输出插入到sort中会将输出按字母/数字顺序组织。

这是必需的,因为uniq仅在重复的行上匹配,即

a
b
a


如果在此文本文件上使用uniq,它将返回以下内容:

a
b
a


这是因为两个ab隔开-它们不是连续的行。但是,如果首先按照字母顺序对数据进行排序,例如

a
a
b


,那么uniq将删除重复行。 -cuniq选项计算重复项的数量,并以以下形式提供输出:

2 a
1 b


参考文献:


sort(1)
uniq(1)


评论


欢迎使用Unix&Linux :)不要犹豫,在您的答案中添加更多详细信息,并解释其原因和工作方式;)

–John WH Smith
2014年11月26日在12:18

printf'%s \ n'①.php②.php|排序uniq -c给我2①.php

–StéphaneChazelas
2014年11月26日12:50

@StéphaneChazelasThats,因为printf打印php \ nphp

–user78605
2014年11月26日13:52

@Jidder,不,这是因为①.php在我的语言环境中与②.php排序相同,因为在我的语言环境中没有为那些①和②字符定义排序顺序。如果想要任何字节值的唯一值(记住文件路径不一定是文本),则需要将语言环境固定为C: LC_ALL = C排序| LC_ALL = C uniq -c。

–StéphaneChazelas
2014年11月26日14:00

为了对结果计数文件进行排序,您应该考虑在下面的@ eduard-florinescu答案中添加“ sort -nr”。

–LluísSuñol
18 Mar 26 '18在11:41

#2 楼

[your command] | sort | uniq -c | sort -nr


几乎可以接受的答案是完整的,您可能想在末尾添加一个额外的sort -nr,以便按照最常出现的行对结果进行排序
uniq选项:

-c, --count
       prefix lines by the number of occurrences


排序选项:

-n, --numeric-sort
       compare according to string numerical value
-r, --reverse
       reverse the result of comparisons


在特定情况下,如果您要排序的行是数字,那么您需要使用sort -gr而不是sort -nr,请参见注释

评论


非常感谢您让我了解-n选项。

– Sigur
16年11月30日17:00

很好的答案,这就是我用来从句子中删除单词计数的方法:tr'''\ n'<$ FILE |排序uniq -c |排序-nr> wordcount.txt。第一个命令用换行符替换空格,从而使其余命令能够按预期工作。

–酒吧
17年7月20日在0:08

使用上面的选项,我在“ 23344”之前得到“ 1”。使用sort -gr可以解决此问题。 -g:根据通用数值进行比较(而不是-n:根据字符串数值进行比较)。

– Peter Jaric
19-2-14在12:24



@PeterJaric很棒的收获,对于了解-gr非常有用,但是我认为uniq -c的输出将像这样-sort -nr将按预期工作

–爱德华(Eduard Florinescu)
19年2月14日在13:09

实际上,当数据为数字时,-gr效果更好。尝试以下两个示例,仅在g和n标志方面有所不同:echo“ 1 11 1 2” | tr'''\ n'|排序uniq -c |排序-nr并回显“ 1 11 1 2” | tr'''\ n'|排序uniq -c |排序-gr。第一个错误排序,但第二个错误。

– Peter Jaric
19年2月15日在10:31

#3 楼

您可以在awk上使用关联数组,然后-(可选)排序:

$ awk ' { tot[
1 c.php
1 d.php
2 b.php
3 a.php
]++ } END { for (i in tot) print tot[i],i } ' access.log | sort


输出:

q4312078q

评论


当管道发送数据时,您将如何计算出现次数?

–user123456
16-10-9的18:00

如果输入列表很大,则此方法非常有价值,因为它不需要将整个列表读入内存然后进行排序。

–neirbowj
19年11月3日在18:01

#4 楼

d.php只有1个样本。这样您会得到很好的输出。

wolf@linux:~$ cat file | sort | uniq -c
      3 a.php
      2 b.php
      1 c.php
      1 d.php
wolf@linux:~$


当有4个d.php时会发生什么?

wolf@linux:~$ cat file | sort | uniq -c
      3 a.php
      2 b.php
      1 c.php
      4 d.php
wolf@linux:~$ 


如果要按出现次数对输出进行排序,则可能需要再次将标准输出发送到sort

wolf@linux:~$ cat file | sort | uniq -c | sort
      1 c.php
      2 b.php
      3 a.php
      4 d.php
wolf@linux:~$ 


使用-r进行反向

wolf@linux:~$ cat file | sort | uniq -c | sort -r
      4 d.php
      3 a.php
      2 b.php
      1 c.php
wolf@linux:~$ 


希望此示例有所帮助

评论


unix.stackexchange.com/a/263849/72456的重复答案

–αғsнιη
20年6月3日,下午5:50