Linux の join コマンドをテキストの抽出に使ってみる

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 だけ抽出できました。

列を指定して抽出できるので抽出条件が他の列に混ざっていても 大丈夫という利点があります。

Google サイト内検索

Amazonアソシエイト