Linuxコンソール上で、ソートせずにユニークな値を取得したい時がある。
例えば、以下のようなファイルからユニークな値を取得する際、よく使われる方法としてはsort+uniqコマンドの組み合わせなのだが、それだと順番がずれてしまう。
あくまでもその文字列が最初に登場した順番でユニークな値を取得したいとする。

[root@BS-PUB-CENT7-01 ~]# cat /tmp/test.txt
test:0
test:2
test:6
test:9
test:4
test:9
test:9
test:9
test:4
test:0
test:2
test:8
test:0
test:7
test:0
[root@BS-PUB-CENT7-01 ~]# cat /tmp/test.txt | sort | uniq
test:0
test:2
test:4
test:6
test:7
test:8
test:9

そんな時は、以下の方法がある。

1.awkで取得する

前にこちらでも触れたことがあるが、awkで以下のようにコマンドを実行することで、同じ文字列が2回目の場合は出力させないようにできる。

コマンド | awk '!a[$1]++'
[root@BS-PUB-CENT7-01 ~]# cat /tmp/test.txt | awk '!a[$1]++'
test:0
test:2
test:6
test:9
test:4
test:8
test:7

2.Perlで取得する

awkと同じように、Perlでも同様の処理が行える。

コマンド | perl -ne 'print unless $seen{$_}++'
[root@BS-PUB-CENT7-01 ~]# cat /tmp/test.txt | perl -ne 'print unless $seen{$_}++'
test:0
test:2
test:6
test:9
test:4
test:8
test:7

3.johnパッケージのuniqueコマンドを利用する

変わり種としては、脆弱性スキャンを行うツールであるjohnパッケージ(John the Ripper)の中にあるuniqueコマンドが同じような動作をする(ただし、一度違うファイルに書き出す必要があるようだ)。

コマンド | unique 出力先PATH
blacknon@BS-PUB-UBUNTU-01:~$ cat /tmp/test.txt | unique /tmp/test.txt.uniq
blacknon@BS-PUB-UBUNTU-01:~$ cat /tmp/test.txt.uniq
test:0
test:2
test:6
test:9
test:4
test:8
test:7