web-dev-qa-db-ja.com

行の出現回数をソートしてカウントする

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 
169
Kokizzu
_| sort | uniq -c
_

コメントで述べたように。

出力をsortにパイプすると、出力がアルファベット順/数値順に整理されます。

uniqは繰り返し行でのみ一致するため、これは要件です。つまり、

_a
b
a
_

このテキストファイルでuniqを使用すると、次が返されます。

_a
b
a
_

これは、2つのabで区切られているためです-連続する行ではありません。ただし、最初にデータをアルファベット順に並べ替えると

_a
a
b
_

次に、uniqは繰り返し行を削除します。 uniqの_-c_オプションは、重複の数をカウントし、次の形式で出力を提供します。

_2 a
1 b
_

参照:

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

受け入れられた回答はほぼ完成しています。最後にsort -nrを追加して、最初に最も頻繁に発生する行で結果を並べ替えることができます。

uniqオプション:

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

sortオプション:

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

並べ替える行が数値である特定のケースでは、sort -grの代わりにsort -nrを使用する必要があります。参照 comment

131

awkに連想配列を使用し、次に-optionally- sortを使用できます。

$ awk ' { tot[$0]++ } END { for (i in tot) print tot[i],i } ' access.log | sort

出力:

1 c.php
1 d.php
2 b.php
3 a.php
12