順序が異なる2つのファイルのデータをマージします。

順序が異なる2つのファイルのデータをマージします。

以下のように2つのファイルがあります。そのホスト名と一致するように、file1からfile2までのID番号を適用する必要があります。必要な出力も下にあります。可能であれば、bashスクリプトを使用してこれを行うことをお勧めしますが、代替方法があります。

ファイル1:

ID: 12345, Name: foo1.bar.com
ID: 12346, Name: foo2.bar.com
ID: 12347, Name: foo3.bar.com
ID: 12348, Name: foo4.bar.com
ID: 12349, Name: foo5.bar.com

ファイル2:

foo3.bar.com
foo4.bar.com
foo1.bar.com
foo5.bar.com
foo2.bar.com

希望の出力 -

12347 foo3.bar.com
12348 foo4.bar.com
12345 foo1.bar.com
12349 foo5.bar.com
12346 foo2.bar.com

この問題を解決するための最良の方法のアイデアはありますか?

答え1

最初のファイルでルックアップテーブル/ハッシュ/関連付けの配列を作成し、2番目のファイルの内容を使用して入力します。

awk -F'[ ,]+' 'NR==FNR {a[$NF] = $2; next} $1 in a {print a[$1], $1}' file1 file2
12347 foo3.bar.com
12348 foo4.bar.com
12345 foo1.bar.com
12349 foo5.bar.com
12346 foo2.bar.com

答え2

サンプルファイルによると、スチールドライバーの回答 (でルックアップテーブル/アソシエーション配列を使用することawk)これはおそらく最良の解決策です。これは通常推奨されませんが、bashでのみ同じことができます。

declare -A id
while IFS=" ," read x idnum xx name
do
        id[$name]=$idnum
done < file1
while read name
do
        printf '%s %s\n' "${id[$name]}" "$name"
done < file2

ロジックは同じです。

  1. 最初のステップでは、ID値を含み、名前値でインデックス付きの配列を作成します。
  2. 2番目のパスでは、名前をIDにマッピングして並べて出力します。

質問のサンプルデータについて、私の答えは予想通り(つまり指定されたとおり)機能します。 (配列、特に連想配列を使用するため、bash(またはksh、zsh、またはyash)が必要です。シェルのPOSIX仕様は配列を指定せず、Unix / .Linuxで使用されているすべてのシェルでは使用できません。)bashコマンドがどのように機能するかによって、read私の答えは直感的に予想されるように、複数の単語で構成される名前(スペースのある名前など)も処理します。

        file1                             file2                    output

ID: 42, Name: fat cat                   fat cat                  42 fat cat
ID: 95, Name: Superman                  under dog                83 under dog
ID: 83, Name: under dog                 spider man      ⟹       17 spider man
ID:  9, Name: cat woman                 spider pig               60 spider pig
ID: 17, Name: spider man                Superman                 95 Superman
ID: 60, Name: spider pig                cat woman                9 cat woman

どちらの答えも大文字と小文字をfoo1.bar.com区別しますFoo1.bar.com

関連情報