awkを使用した2つのファイルのマージ

awkを使用した2つのファイルのマージ

1、2、3列に基づいて2つのファイルをマージしたいと思います。次のコマンドを試しましたが、awk機能しません。

awk 'NR==FNR {h[$1FS$2FS$3]=$4; next}{k=$1FS$2FS$3; if (k in h) print $1,$2,$3,$4,h[k] ;else print $1,$2,$3,$4,"NA"}1' FS=\| OFS=\| file2.txt 

ファイル1.txt:

Student1|Class 1A|27|20140804 08:16:54
Student2|Class 1B|15|20140804 10:10:10
Student3|Class 1C|17|20140804 15:02:14
Student4|Class 1D|20|20140804 18:02:14
Student5|Class 2D|10|20140804 20:02:14

ファイル2.txt:

Student1|Class 1A|27|20140805 08:16:54
Student2|Class 1B|15|20140805 10:10:10
Student4|Class 1D|20|20140805 18:02:14
Student5|Class 2D|10|20140805 20:02:14

予想される結果:

Student1|Class 1A|27|20140804 08:16:54|20140805 08:16:54
Student2|Class 1B|15|20140804 10:10:10|20140805 10:10:10
Student3|Class 1C|17|20140804 15:02:14|NA
Student4|Class 1D|20|20140804 18:02:14|20140805 18:02:14
Student5|Class 2D|10|20140804 20:02:14|20140805 20:02:14

答え1

この試み。あなたの例のように配列を作成し、マージされたフィールドのみを印刷しますEND { ... }

$ awk -F\| '{ k=$1 FS $2 FS $3; h[k] = (k in h) ? h[k]=h[k] FS $4 : $0 } END { for(x in h){printf "%s%s\n",h[x],(length(h[x])>38) ? "" : "|NA"}}' file1.txt file2.txt|sort
Student1|Class 1A|27|20140804 08:16:54|20140805 08:16:54
Student2|Class 1B|15|20140804 10:10:10|20140805 10:10:10
Student3|Class 1C|17|20140804 15:02:14|NA
Student4|Class 1D|20|20140804 18:02:14|20140805 18:02:14
Student5|Class 2D|10|20140804 20:02:14|20140805 20:02:14
$

答え2

最初のファイルにフルキーリスト(学生など)が含まれていると仮定するのが安全な場合は、まず各レコードに追加できます。その後は、END次のものが必要です。タイプキーを使用して追加の値を切り捨て、不足している値を次に埋めます"NA"

$ awk -F\| '{k=$1 FS $2 FS $3;r[k]=r[k] FS $4;c[k]++}
    END{n=asorti(r,s);
        for(i=1;i<=n;i++){
            print s[i] substr(r[s[i]],1) (++c[s[i]] == ARGC ? "" : FS "NA")
        }
    }' file1.txt file2.txt
Student1|Class 1A|27|20140804 08:16:54|20140805 08:16:54
Student2|Class 1B|15|20140804 10:10:10|20140805 10:10:10
Student3|Class 1C|17|20140804 15:02:14|NA
Student4|Class 1D|20|20140804 18:02:14|20140805 18:02:14
Student5|Class 2D|10|20140804 20:02:14|20140805 20:02:14

私はバックフィル比較を実行するためにファイル数+ 1(つまり、コマンド自体)を使用するように指示する++c[s[i]] == ARGCを使用しています。ARGCawk

答え3

私はそれを試して動作します

/usr/xpg4/bin/awk 'NR==FNR {h[$1,$2,$3]=$4; next}{print $0,($1,$2,$3) in h?h[$1,$2,$3]:"NA"}' FS=\| OFS=\| file2.txt file1.txt

関連情報