我有记录。一条记录具有以下格式:
<client host> - - [<timestamp with timezone>] <HTTP-request line (type, URL, version)> <Code of HTTP-response> <Number of sent bytes or '-', if the response is empty> <Referer string ('-' means direct request without referer)> <Client info (browser, application)>
例如这 5 行:
20158147070.user.veloxzone.com.br - - [29/Oct/2006:06:59:18 -0700] "GET /example/.comments
HTTP/1.1" 404 293 "http://www.example.org/example/" "Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1; SV1)"
20158147070.user.veloxzone.com.br - - [29/Oct/2006:06:59:18 -0700] "GET /example/.comments
HTTP/1.1" 404 293 "http://www.example.org/example/" "Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1; SV1)"
adorno.ub.uni-duesseldorf.de - - [10/Oct/2006:06:59:37 -0700] "GET /example/.comments
HTTP/1.0" 404 281 "-" "Mozilla/5.0 (Windows; U; WinNT4.0; de-DE; rv:1.0.2) Gecko/20030208
Netscape/7.02"
nat240.ariba.com - - [29/Oct/2006:07:40:47 -0700] "GET //example/example.atom' HTTP/1.1" 304
298 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909
Thunderbird/1.5.0.7"
nat240.ariba.com - - [31/Oct/2006:07:10:47 -0700] "GET /example/example.atom' HTTP/1.1" 304
297 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909
Thunderbird/1.5.0.7"
我需要按 url 名称对其进行排序,而不考虑该行的其余部分。
我使用 awk 查找 404 错误,现在我需要排序
cat log.txt | gawk '$9=="404"' | gawk '{print $7 , $9}' | uniq -c | sort -r
但我有这个:
2 /example/.comments 404
1 /example/.comments 404
我需要这样的:
3 /example/.comments 404
…………
1. /example/.comments - 28 - 32.2%
2. /example/example.atom.xml - 9 - 10.3%
3. /example/When/200x/2003/04/10/-big/Concorde.jpg - 8 - 9.2%
4. /example/When/200x/2006/03/30/-big/IMG_4613.jpg - 7 - 8.0%
5. /example/When/200x/2003/07/25/-big/guild-2.jpg - 6 - 6.9%
6. /example/Patti-Smith.png - 5 - 5.7%
7. /example/IMGP4289-2.png - 5 - 5.7%
8. /example/IMGP4287.png - 5 - 5.7%
9. /example/Image-Search-Mystery.png - 5 - 5.7%
10. /example/Horses.png - 5 - 5.7%
11. /example/When/200x/2004/02/27/-big/Unreal.png - 4 - 4.6%
格式为:列表或计数器,后跟名称 url,后跟它们的唯一编号,再后跟它们占所有 404 错误的百分比。
答案1
您应该始终sort
在使用uniq
命令之前使用。工作方式uniq
是,它仅在重复项逐一排列时才计算重复项,如果同一行在某些不同行之后有几行,则该行不会被计入先前的重复项。
您应该始终使用sort
和 管道 touniq -c
来获取相同行的准确计数。
另外,由于第一列将是一些计数,sort -n
如果您希望按出现次数对它们进行排序,则应该使用它们。
您还可以删除第一只猫并直接对文件而不是输出执行 awk cat
。
你应该使用这样的东西:
gawk '$9=="404"' log.txt | gawk '{print $7 , $9}' | sort | uniq -c | sort -n
sort -k
如果您不想按计数排序,也可以使用按第二列排序。
gawk '$9=="404"' log.txt | gawk '{print $7 , $9}' | sort | uniq -c | sort -k 2
如果您不需要计算行数,则可以使用 sort -u 来获取唯一行,并且可以将两个 awk 管道合并为一个。
gawk '$9=="404" {print $7 , $9}' log.txt | sort -u
如果您想按出现次数排序并在一个命令中计算所有 404,您需要在 awk 中执行以下操作:
gawk '{PROCINFO["sorted_in"] = "@val_num_asc"} $9=="404" {count_url[$7]++} {count_404[$9]++} END {for(url in count_url) print count_url[url],url;print "number of 404 errors: "count_404[404];}' log.txt