Bash

Linux・Bashコマンドでファイルの重複する行を削除して取得する方法まとめ

以下を参照すると、ファイルの重複ラインを削除するコマンドのとり方は多くあることに気づきます。

shell – Remove duplicate entries using a Bash script – Stack Overflow

今回はそれぞれのコマンドの出力を比較した上で、興味深い検証結果が出ましたので、そちらとともに紹介していきたいと思います。

まずは以下の通り、hogeが重複しているfuga.txtを例として検証してみます。


$ cat > fuga.txt hoge fuga foo hoge bar $ cat fuga.txt | sed '$!N; /^\(.*\)\n\1$/!P; D' hoge fuga foo hoge bar $ cat fuga.txt | sort -u bar foo fuga hoge $ cat fuga.txt | awk '!a[$0]++' hoge fuga foo bar

sed '$!N; /^\(.*\)\n\1$/!P; D'では、連続している重複行でないため重複行hogeは削除されませんでした。

sort -uは並び替え処理をしてから重複行を削除するため、本来のファイル内容と大きく結果が異なっています。

awk '!a[$0]++'は特に問題なくできているように見えますね。

続いて以下にて検証してみます。興味深い結果となりました。


$ cat > fuga.txt りんご ぱいん [りんご] りんご ぱぷりか [りんご] なす $ cat fuga.txt | sed '$!N; /^\(.*\)\n\1$/!P; D' りんご ぱいん [りんご] りんご ぱぷりか [りんご] なす $ cat fuga.txt | sort -u [りんご] なす りんご ぱぷりか $ cat fuga.txt | awk '!a[$0]++' りんご ぱいん [りんご] ぱぷりか なす

お気づきでしょうか。sort -uawk '!a[$0]++'の出力結果の行数が異なっていますね。awkの方では維持されている非重複行”ぱいん”が、sortの方では抜け落ちています。

考えてみましたが、原因はわかりませんでした。バグだと思っていいでしょう。

このような結果から、ファイルの重複行削除に関しては、並び順を維持しつつ、バグも無いであろうawk '!a[$0]++'が一番適しているコマンドであると思われます。