web-dev-qa-db-ja.com

AWKを使用して2つのファイルをマージする方法は?

ファイル1には5つのフィールドA B C D Eがあり、フィールドAは整数値です

ファイル2には3つのフィールドA F Gがあります

ファイル1の行数は、ファイル2の行数よりはるかに大きい(20 ^ 6〜5000)

ファイル1のAのすべてのエントリは、ファイル2のフィールドAに現れました。

私はフィールドAで2つのファイルをマージし、FとGを運ぶのが好きです

望ましい出力はA B C D E F G

ファイル1

 A     B     C    D    E
4050 S00001 31228 3286 0
4050 S00012 31227 4251 0
4049 S00001 28342 3021 1
4048 S00001 46578 4210 0
4048 S00113 31221 4250 0
4047 S00122 31225 4249 0
4046 S00344 31322 4000 1

ファイル2

A     F    G   
4050 12.1 23.6
4049 14.4 47.8   
4048 23.2 43.9
4047 45.5 21.6

望ましい出力

A    B      C      D   E F    G
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
31
Tony
$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
4046 S00344 31322 4000 1
36
kurumi

ありがたいことに、これを書く必要はまったくありません。 Unixには、これを行うためのjoinコマンドがあります。

join -1 1 -2 1 File1 File2

これは「実行中」です。

will-hartungs-computer:tmp will$ cat f1
4050 S00001 31228 3286 0
4050 S00012 31227 4251 0
4049 S00001 28342 3021 1
4048 S00001 46578 4210 0
4048 S00113 31221 4250 0
4047 S00122 31225 4249 0
4046 S00344 31322 4000 1
will-hartungs-computer:tmp will$ cat f2
4050 12.1 23.6
4049 14.4 47.8   
4048 23.2 43.9
4047 45.5 21.6
will-hartungs-computer:tmp will$ join -1 1 -2 1 f1 f2
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
will-hartungs-computer:tmp will$ 
26
Will Hartung

ファイル2のエントリを、BEGINブロックの連想配列のペアに読み込む必要があります。 GNU Awk:

BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }

メイン処理ブロックで、ファイル1から行を読み取り、BEGINブロックで作成された配列の正しいデータを使用して印刷します。

{ print $0, f[$1], g[$1] }

ファイル1をプログラムのファイル名引数として指定します。

awk 'BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
     print $0, f[$1], g[$1] }' "File 1"

ファイル名にスペースがあるため、ファイル名引数を引用符で囲む必要があります。 getlineファイル名は、スペースが含まれていない場合でも、変数名になるため、引用符で囲む必要があります。

5