web-dev-qa-db-ja.com

フィールドの一致に基づいて2つのファイルをマージする

2つの入力ファイルの列を含むファイルを作成します。 File1は次のようなものです。

aa 32
bb 15
cc 78

File2は次のとおりです。

fa 19
bc 23
cc 50
de 28
aa 45
bb 31

タスクは、File1を介して読み取られ、行の最初のフィールドがFile2の最初のフィールドの中に存在する場合、File2のその行を両方の列とともに印刷し、最初のフィールドを含むFile1の2番目の列エントリを追加します。

出力は次のようになります。

aa 45 32
bb 31 15
cc 50 78

スクリプトにはawkが推奨されます。

4
hldn
$ awk 'FNR==NR{a[$1]=$2;next} ($1 in a) {print $1,a[$1],$2}' file2 file1
aa 45 32
bb 31 15
cc 50 78

説明:

awkは、各ファイルを1行ずつ暗黙的にループします。最初の引数としてfile2を指定したため、最初に読み取られます。 file1は2番目に読み取られます。

  • FNR==NR{a[$1]=$2;next}

    NRawkがこれまでに読み取った行数であり、FNRawkが現在のファイルからこれまでに読み取った行数です。したがって、FNR==NRの場合でも、最初の名前付きファイルfile2を読み取っています。 file2のすべての行に、a[$1]=$2を割り当てます。

    ここで、a連想配列であり、a[$1]=$2は、file2の2番目の列($2と表記)を配列aの値として保存することを意味します。 file2の最初の列、$1をキーとして。

    nextは、残りのコマンドをスキップして次の行からやり直すようにawkに指示します。

  • ($1 in a) {print $1,a[$1],$2}

    ここに到達した場合は、2番目のファイルfile1を読み取っていることを意味します。配列aの内容によって決定されるfile2の行の最初のフィールドを確認した場合、両方のファイルからフィールド2の値を含む行を出力します。

8
John1024

私はawkソリューションが好きですが、これはもっと簡単かもしれません:

sort file1 > sortedFile1
sort file2 > sortedFile2
join -o 1.1 2.2 1.2 sortedFile1 sortedFile2

オプション -oは、最初のファイルの最初のフィールド、2番目のファイルの2番目のフィールド、最初のファイルの2番目のフィールドとして選択する形式を上書きします。

3
Isaac

2番目のファイルに結合、File2を最初のファイルに、File1

join <(sort -k1 file2) <(sort -k1 file1)
0
Abishek J