BashコマンドTips2

BashコマンドTips2

その2
sort uniqを高速でやろうという話。
技術的なところというよりは、マニュアルを読もうという話かもしれない。

ファイルをソートして重複を取り除く

割とよくある作業で、二つのファイルをソートしてユニークしたいというのがあると思う。

例えばこんな二つのファイルがある。

$ cat hoge.txt
aaa
bbb
ccc
ccc
dddd

$ cat fuga.txt
bbb
bbb
ccc
dddd
ff
gg
gg

これらのファイルをマージして、重複するものを取り除きたいとする。
王道コマンドとしては、こうなる

$ time cat hoge.txt fuga.txt | sort | uniq
aaa
bbb
ccc
dddd
ff
gg

real 0m0.043s
user 0m0.000s
sys 0m0.030s

このくらいのデータ量だと気にするほどの時間でもないのだが、こんな感じで出せる。

高速化

ここでsortのマニュアルを見てみると、こんな記述がある。

-m, --merge
merge already sorted files; do not sort

つまり、すでにソートされたファイルであれば
以下のようにソートされた状態でマージすることができる。

$ sort -m fuga.txt hoge.txt
aaa
bbb
bbb
bbb
ccc
ccc
ccc
dddd
dddd
ff
gg
gg

で、さらにこんな記述もある。
<div class=”code-block”>-u, –unique
with -c, check for strict ordering; without -c, output only the
first of an equal run</div>
-cがなければ、単純に一番上から、
下のものが等しいかだけ走らせる、といったことが書いてある。
つまりuniqコマンドに相当することをしてくれる。

なので、上二つを組み合わせると・・・

$ time sort -mu fuga.txt hoge.txt
aaa
bbb
ccc
dddd
ff
gg

real 0m0.025s
user 0m0.000s
sys 0m0.000s

と、この通りである。
最初の結果と比較してみる

real 0m0.043s
user 0m0.000s
sys 0m0.030s

real 0m0.025s
user 0m0.000s
sys 0m0.000s

相当早くなっていることがわかる。
二つともソートされているファイルであることが条件ではあるが、
高速でソートを行うことができる。
更に、catやuniqを書かないので、コード量も削減できるというわけである。