ソート済みのファイルの、重複する項目を出力するワンライナー

重複する項目を出力するワンライナーを書く。ファイルはソート済みであるとする。ここでは、/usr/bin/ にあるファイルの先頭 3 文字とファイルサイズを例にとる。

[takeyuki@sunya ~]$ ls -l /usr/bin | awk '$9==""{next}{print substr($9,1,3),$5}' | sort | head -30
GET 14673
HEA 14673
HtF 2633
Mai 14
POS 14673
RSA 8300
X 4
Xne 3828008
Xor 1890084
Xvf 4144360
Xvn 4378736
[ 31048
a2p 111180
a2p 352412
ab 47556
ac 20520
acl 11405
acl 12387
acl 12596
acl 13161
acl 19848
acl 19848
aco 16720
acp 9912
acr 31
act 12724
add 27344
add 80228
add 8140
afs 63380

行まるまる重複するものを出力するには uniq コマンドの -D オプション (--all-repeated) を使えばよい。

[takeyuki@sunya ~]$ ls -l /usr/bin | awk '$9==""{next}{print substr($9,1,3)}' | sort | uniq -D | head
a2p
a2p
acl
acl
acl
acl
acl
acl
add
add

しかし、重複を調べる対象を最初のフィールドだけに限定することはできない (逆に最初のフィールドをスキップして重複を調べることは -f オプション (--skip-fields) で指定できる)。
そこで awk の出番。

[takeyuki@sunya ~]$ ls -l /usr/bin | awk '$9==""{next}{print substr($9,1,3),$5}' | sort | awk 'p==$1{print p,v;s=1}p!=$1&&s>0{print p,v;s=0}{p=$1;v=$2}END{if(s>0)print p,v}' | head
a2p 111180
a2p 352412
acl 11405
acl 12387
acl 12596
acl 13161
acl 19848
acl 19848
add 27344
add 80228