join というコマンドがあります。
配列を文字列に結合する join もありますが データベースを使ってる人ならテーブルの結合を 思い浮かべるのではないでしょうか。 そちらのイメージです。
まずは paste コマンドのおさらい。
次の 2 つのファイル sugaku.txt と kokugo.txt を処理します。
ito 98 1 kameda 83 2 tanaka 71 3 wada 32 4
ito 91 2 tanaka 100 1 wada 45 3
数学と国語のテスト結果で、「名前、点数、順位」が テキストファイルに書かれています。
join します。
$ join sugaku.txt kokugo.txt ito 98 1 91 2 tanaka 71 3 100 1 wada 32 4 45 3 ~~~~|~~~~ ~~~~|~~~~ sugaku.txtの内容 kokugo.txtの内容
2 つのファイルが 1 つにまとまりました。
オプションなしの場合、1 列目の値を使って結合します。
kokugo.txt に kameda の行はなかったため除外されました。 データベーステーブルの内部結合と同じです。
結合条件となる列を変えることもできますが、
あらかじめソートされている必要があります。
順位で結合するために kokugo.txt を順位の列でソートして
kokugo2.txt を作ります。
( sugaku.txt は順位の列も昇順になっているのでソート不要)
$ sort +2 -n kokugo.txt > kokugo2.txt $ cat kokugo2.txt tanaka 100 1 ito 91 2 wada 45 3
3 列目の順位の列で join します。
$ join -1 3 -2 3 sugaku.txt kokugo2.txt 1 ito 98 tanaka 100 2 kameda 83 ito 91 3 tanaka 71 wada 45 ~~~~|~~~~~ ~~~~|~~~~~~ sugaku.txtの内容 kokugo2.txtの内容
"-1" は 1 つ目のファイルの結合条件となる列を指定します。 "-2" は 2 つ目のファイルの結合条件となる列です。
結合条件となる列は 先頭に出力されます。
ファイルの 1 つを標準入力から受けることもできます。 その場合、ファイルの指定の変わりにハイフン "-" を指定します。
$ cat sugaku.txt | join -1 3 -2 3 - kokugo2.txt 1 ito 98 tanaka 100 2 kameda 83 ito 91 3 tanaka 71 wada 45
これを利用して 標準入力から受けたコマンドの出力結果のテキストを 抽出してみたいと思います。
ls の結果が次のようになるとします。
$ ls -l
-rw-r--r-- 1 hoge hoge 54 May 31 04:12 a.txt
-rw-r--r-- 1 hoge hoge 54 May 31 04:12 b.txt
-rw-r--r-- 1 hoge hoge 54 May 31 04:12 c.txt
-rw-r--r-- 1 hoge hoge 54 May 31 04:12 d.txt
まず次のようなテキスト( where.txt )を用意します。
a.txt b.txt
join します。
$ ls -l | join -1 9 - where.txt
a.txt -rw-r--r-- 1 hoge hoge 54 May 31 04:12
b.txt -rw-r--r-- 1 hoge hoge 54 May 31 04:12
a.txt と b.txt だけ抽出できました。
列を指定して抽出できるので抽出条件が他の列に混ざっていても 大丈夫という利点があります。