1. 概要

このチュートリアルでは、 join コマンドの使用方法を調べ、いくつかの例を示します。

2. 参加

join コマンドを使用すると、ファイルの関連行間のリンクとして、各ファイルの共通フィールドを使用して2つのファイルをマージすることができます。

Linux join コマンドは、リレーショナルデータベース内の2つ以上のテーブルを結合する場合のSQL結合と同じように考えることができます。

これを行うには、各テーブルに共通のフィールドが必要です。これらのフィールドを使用して、テーブル間の関係を形成できます。 Linuxでファイルを結合する場合も同じことが言えます。つまり、joinにファイル内の行が互いにどのように関連しているかを知らせる方法が必要です。

入力ファイルをsortしないと、不正確な結果が予想されます。 入力ファイルを共通フィールドで並べ替える必要があります。

3. 例

まず、例で使用するサンプルファイルをいくつか作成しましょう。 デバイスのIPアドレスを共通フィールドとして使用して2つのログファイルを結合するシナリオを作成します。

最初のファイルには、デバイスのIPアドレスとマシン名が含まれます。

$ cat << EOF > device_names.log
10.0.1.10 WINSHARE01
10.0.1.13 WEBSERVER03
10.0.1.15 FINSERVER02
143.204.74.129 WEBSERVER02
152.120.106.21 HRSERVER01
192.168.8.28 MYWORKSTATION
192.168.10.4 PRINTER02
EOF

2番目のファイルには、各デバイスのインターネットアクセスのレベルを定義するインターネットブラウジングポリシーを追加します。

$ cat << EOF > device_policies.log
10.0.1.10 RED
10.0.1.13 YELLOW
10.0.1.15 RED
143.204.74.129 YELLOW
152.120.106.21 BLUE
192.168.8.28 GREEN
192.168.10.4 RED
EOF

いくつかの例に入る前に、サンプルデータについて説明しましょう。 各ファイルは最初のフィールドとしてIPアドレスで始まります。これは、デフォルトで joinが、最初のフィールドがファイル間の共通フィールドであると想定しているためです。 また、フィールド間の区切り文字としてスペース文字を使用しています。これもjoinのデフォルトです。

3.1. ソートされたファイルの結合

両方のログファイルをIPアドレスで並べ替え、デフォルトのスペース区切り文字を使用するように注意しているため、joinコマンドの最も簡単な呼び出しを実行できます。

$ join device_names.log device_policies.log
10.0.1.10 WINSHARE01 RED
10.0.1.13 WEBSERVER03 YELLOW
10.0.1.15 FINSERVER02 RED
143.204.74.129 WEBSERVER02 YELLOW
152.120.106.21 HRSERVER01 BLUE
192.168.8.28 MYWORKSTATION GREEN
192.168.10.4 PRINTER02 RED

結果の出力には、回線ごとに関連する各デバイスのIPアドレス、デバイス名、およびインターネットポリシーが表示されます。

3.2. ソートされていないファイルの結合

device_policies.log のコピーを作成し、順序を少し変更して、並べ替えられていないファイルを処理する方法を確認しましょう。

$ cat &lt;&lt; EOF &gt; device_policies_unordered.log
10.0.1.10 RED
10.0.1.13 YELLOW
10.0.1.15 RED
143.204.74.129 YELLOW
192.168.8.28 GREEN
192.168.10.4 RED
<strong>152.120.106.21 BLUE</strong>
EOF

次に、代わりに device_policies_unordered.log ファイルを使用して、基本的なjoinコマンドを発行しましょう。

$ join device_names.log device_policies_unordered.log
10.0.1.10 WINSHARE01 RED
10.0.1.13 WEBSERVER03 YELLOW
10.0.1.15 FINSERVER02 RED
143.204.74.129 WEBSERVER02 YELLOW
<strong>join: device_names.log:7: is not sorted: 192.168.10.4 PRINTER02
join: device_policies_unordered.log:6: is not sorted: 192.168.10.4 RED</strong>
192.168.8.28 MYWORKSTATION GREEN
192.168.10.4 PRINTER02 RED

現在、出力は異なって見えます。 また、いくつかの情報メッセージも表示されます。 ファイルは同じように並べ替えられていないため、出力にエラーメッセージが表示されます join は、正しく対応しているファイルの行と引き続き一致します。

幸い、マージを実行する前に入力ファイルをテストする方法があります。 –check-orderフラグを渡して、joinが入力ファイルが正しくソートされていることを確認します。今度は –check-orderを使用して、一致しないファイルを再度結合しようとするとどうなるか見てみましょう。 フラグ:

$ join --check-order device_names.log device_policies_unordered.log
10.0.1.10 WINSHARE01 RED
10.0.1.13 WEBSERVER03 YELLOW
10.0.1.15 FINSERVER02 RED
143.204.74.129 WEBSERVER02 YELLOW
join: device_names.log:7: is not sorted: 192.168.10.4 PRINTER02

この例では、 join はレコードのマージを開始しましたが、正しくソートされていないレコードの最初のインスタンスを見つけると停止しました。

たとえば、スクリプトのステップとして join を使用する場合、一致しないレコードを無視して、正しくソートされたレコードの結合を続行したい場合があります。 –nocheck-order フラグは、その正確な動作を提供します。

一致しない行を気にせずに、不一致のファイルを再度結合してみましょう。

$ join --nocheck-order device_names.log device_policies_unordered.log
10.0.1.10 WINSHARE01 RED
10.0.1.13 WEBSERVER03 YELLOW
10.0.1.15 FINSERVER02 RED
143.204.74.129 WEBSERVER02 YELLOW
192.168.8.28 MYWORKSTATION GREEN
192.168.10.4 PRINTER02 RED

この出力は、 join、 –nocheck-order フラグを使用することにより、ファイルを正常に処理し、一致するすべての行を受信し、予期しない障害が発生しないものを無視することを示しています。エラーメッセージ。

3.3. カスタムセパレータを使用したファイルの結合

joinにカスタムセパレーターを提供する方法が必要です。 -tオプションを使用して結合に値を渡すことにより、結合に使用するカスタムセパレーターを提供します。

ログファイルを更新し、フィールド間の区切り文字としてコンマを使用して変更しましょう。

$ cat << EOF > device_names_comma.log
10.0.1.10,WINSHARE01
10.0.1.13,WEBSERVER03
10.0.1.15,FINSERVER02
143.204.74.129,WEBSERVER02
152.120.106.21,HRSERVER01
192.168.8.28,MYWORKSTATION
192.168.10.4,PRINTER02
EOF
$ cat << EOF > device_policies_comma.log
10.0.1.10,RED
10.0.1.13,YELLOW
10.0.1.15,RED
143.204.74.129,YELLOW
152.120.106.21,BLUE
192.168.8.28,GREEN
192.168.10.4,RED
EOF

次に、これら2つの新しいコンマ区切りのログファイルをマージしてみましょう。

$ join -t , device_names_comma.log device_policies_comma.log
10.0.1.10,WINSHARE01,RED
10.0.1.13,WEBSERVER03,YELLOW
10.0.1.15,FINSERVER02,RED
143.204.74.129,WEBSERVER02,YELLOW
152.120.106.21,HRSERVER01,BLUE
192.168.8.28,MYWORKSTATION,GREEN
192.168.10.4,PRINTER02,RED

カスタム区切り文字を使用して、レコードを正常にマージしました。

3.4. 最初のファイルの別のフィールドを使用してファイルを結合する

共通フィールドは、必ずしも各ファイルの最初のフィールドであるとは限りません。 異なる順序で表示されるフィールドを使用してファイルを結合できる必要があります。 device_names.logファイルのフィールドの順序を変更してみましょう。

$ cat << EOF > device_names_reverse.log
WINSHARE01 10.0.1.10
WEBSERVER03 10.0.1.13
FINSERVER02 10.0.1.15
WEBSERVER02 143.204.74.129
HRSERVER01 152.120.106.21
MYWORKSTATION 192.168.8.28
PRINTER02 192.168.10.4
EOF

device_names_reverse.logdevice_policies.logを結合しようとすると、共通フィールド(IPアドレス)が両方のファイルの最初のフィールドではなくなったため、操作が失敗することが予想されます。

幸い、 join のデフォルトの動作をオーバーライドして、共通フィールドとして使用する最初のファイルのフィールド番号を渡すことができます。

$ join -1 2 device_names_reverse.log device_policies.log
10.0.1.10 WINSHARE01 RED
10.0.1.13 WEBSERVER03 YELLOW
10.0.1.15 FINSERVER02 RED
143.204.74.129 WEBSERVER02 YELLOW
152.120.106.21 HRSERVER01 BLUE
192.168.8.28 MYWORKSTATION GREEN
192.168.10.4 PRINTER02 RED

-1 オプションを使用すると、両方のファイルで共通フィールドの順序が同じでないファイルを結合できます。 -1 オプションの値として、最初のファイルの共通フィールドの位置を渡すだけです。 -1 オプションは、joinコマンドの引数にリストされている最初のファイルを非常に単純に参照します。

3.5. 2番目のファイルの別のフィールドを使用してファイルを結合する

ここで、引数の順序を少し変更して、2番目のファイルで同じ動作を実現する方法を見てみましょう。

$ join -2 2 device_policies.log device_names_reverse.log
10.0.1.10 RED WINSHARE01
10.0.1.13 YELLOW WEBSERVER03
10.0.1.15 RED FINSERVER02
143.204.74.129 YELLOW WEBSERVER02
152.120.106.21 BLUE HRSERVER01
192.168.8.28 GREEN MYWORKSTATION
192.168.10.4 RED PRINTER02

-1 オプションの使用から、引数リストの2番目のファイルを参照する-2の使用に変更しました。 -2 オプションの値として、共通フィールドの位置を渡します。

別の簡単な変更を行い、device_policies.logファイルのフィールドの順序を逆にしましょう。

$ cat << EOF > device_policies_reverse.log
RED 10.0.1.10 
YELLOW 10.0.1.13 
RED 10.0.1.15 
YELLOW 143.204.74.129 
BLUE 152.120.106.21 
GREEN 192.168.8.28 
RED 192.168.10.4 
EOF

3.6. 両方のファイルで異なるフィールドを使用してファイルを結合する

ファイルの順序を入れ替えて、最初のフィールドとしてポリシーグループを配置し、2番目のフィールドとしてIPアドレスを配置しました。 これは、device_names_reverse.logファイルと同じ順序です。 したがって、現在、共通フィールドであるIPアドレスは両方のファイルで同じ位置にあります。

このシナリオに対応するためにjoinを呼び出す方法を見てみましょう。

$ join -j 2 device_names_reverse.log device_policies_reverse.log
10.0.1.10 WINSHARE01 RED
10.0.1.13 WEBSERVER03 YELLOW
10.0.1.15 FINSERVER02 RED
143.204.74.129 WEBSERVER02 YELLOW
152.120.106.21 HRSERVER01 BLUE
192.168.8.28 MYWORKSTATION GREEN
192.168.10.4 PRINTER02 RED

-j オプションを使用して、 join に、それぞれの各ファイルの共通フィールドに同じフィールド位置の参照を使用するように指示します。

3.7. 出力のカスタマイズ

過去の例では、 join が最初のファイルのレコードを出力し、続いて2番目のファイルの対応するレコードを出力する方法を見てきました。 -oオプションを使用して、使用するカスタム出力形式で結合を提供できます

$ join -t , -o 1.1,2.2,1.2 device_names_comma.log device_policies_comma.log
10.0.1.10,RED,WINSHARE01
10.0.1.13,YELLOW,WEBSERVER03
10.0.1.15,RED,FINSERVER02
143.204.74.129,YELLOW,WEBSERVER02
152.120.106.21,BLUE,HRSERVER01
192.168.8.28,GREEN,MYWORKSTATION
192.168.10.4,RED,PRINTER02

の表記を使用して 出力をどのように表示するかを定義できます。 引数リストの最初のファイルをjoin1と呼び、2番目のファイルを2と呼びます。 フィールド番号は1から始まります。 選択した区切り文字で出力を区切ります。

4. 結論

このチュートリアルでは、 join コマンドを発見し、例として、その使用法のいくつかを調査しました。 また、 join のデフォルトの動作をオーバーライドして、使いやすさを向上させる方法についても説明しました。

いつものように、 join コマンドの詳細については、のマニュアルページを参照してください。