[Linux]複数ファイルを統合して重複を省いたリストを作る

シチュエーション

ユーザー名、商品名など、何かしらの値が一列に記載されたテキストが複数あるとします。

file_1

hoge
fuga

file_2

hoge
piyo

file_3

foo
bar
piyo

これらをまとめて、かつ重複を排除したリストを作りたい、
という場合。

Google Spreadsheetをよく使う人だと、「各テキストの中身を転記してUNIQUE関数で重複を省けば…」と考えてしまうのではないでしょうか。
実際それでできるのですが、地味に時間が掛かります。

結論

Linuxコマンドを使えば一行のコマンドでいけます。

$ cat file_1 file_2 file_3 | sort | uniq > single_file

解説

cat : ファイルの中身を出力する

$ cat file名
でfileの中身を出力します。

file名を続けて書くことで、続けて出力してくれます。

$ cat file_1                           
hoge
fuga

$ cat file_1 file_2 file_3             
hoge
fuga
hoge
piyo
foo
bar
piyo

嬉しいことに、catではワイルドカードで指定できます。これによって、複数ファイルを楽に指定できます。

$ ls file_*
file_1 file_2 file_3 not_file_1

# not_file_1を含まず、file_1, file_2, file_3を指定
$ cat file_*                       
hoge
fuga
hoge
piyo
foo
bar
piyo

sort : 並べ替える

$ cat file名
で、出力内容を並べ替えることができます。

並べ替えは次のuniqで必要な手順です。

前項の結果を|(パイプ)でつなぐことで、catした結果に対してsort、という処理になります。

$ cat file_1 file_2 file_3 | sort
bar
foo
fuga
hoge
hoge
piyo
piyo

余談ですが複数列のtsvファイルなどで、例えば2列目の値を基準に並べ替えることもできます。
$ sort -k 2 file名

uniq : 重複行を省く

$ uniq ファイル名
で、連続して重複する行を省いてくれます。
「連続して」という条件があるので、さきほどsortしたわけですね。

sortした結果を|でつなぎます。

$ cat file_1 file_2 file_3 | sort | uniq
bar
foo
fuga
hoge
piyo

> : リダイレクトでファイルに書き込み

ここまでの出力結果を、ファイル名を付けて書き込みます。

以上でできました。

参考