web-dev-qa-db-ja.com

2つの共通フィールドで2つのファイルを結合する

2つのファイルがあります

file1.txt

78Z|033333157|0000001|PERD1|2150421|D|0507020|3333333311
78Z|033333157|0000001|PERD0|2160208|A|1900460|3333333311
78Z|033333157|0000001|RSAB1|2150421|D|0507070|3333333311
78Z|033333157|0000001|RSAB0|2160208|A|1900460|3333333311
78Z|033333157|0000001|ANT37|2141023|D|1245260|3333333311
78Z|033333157|0000001|ANT36|2150422|D|1518490|3333333311
78Z|033333157|0000001|ANT28|2150321|D|0502090|3333333311
78Z|033333157|0000001|ANT27|2150122|D|0501450|3333333311
78Z|033333157|0000001|ANT26|2141222|D|1637460|3333333311
78Z|033333157|0000001|ANT10|2160208|A|1900460|3333333311
78Z|033333157|0000001|ABS10|2151221|D|1223390|3333333311
78Z|696931836|0000001|PERD0|2160203|A|1114450|2222222222
78Z|696931836|0000001|RSAB0|2160203|A|1114450|2222222222
78Z|696931836|0000001|ANT09|2160203|A|1114450|2222222222
78Z|010041586|0000001|PERD0|2160119|A|1835100|3333333333
78Z|010041586|0000001|RSAB0|2160119|A|1835100|3333333333
78Z|010041586|0000001|ANT33|2160119|A|1835100|3333333333
78Z|011512345|0000001|PERD0|2151213|A|1413550|4444444444
78Z|011512345|0000001|RSAB0|2151213|A|1413550|4444444444
78Z|011512345|0000001|ANT32|2160219|A|0319230|4444444444
78Z|011512345|0000001|ANT09|2160218|D|0319230|4444444444
78Z|011512345|0000001|ANT07|2150729|D|1508230|4444444444
78Z|011512345|0000001|ANT06|2141013|D|1208190|4444444444
78Z|011512345|0000001|ABB06|2131224|D|1857030|4444444444
78Z|012344052|0000001|PERD0|2160203|A|1219570|5555555555
78Z|012344052|0000001|ANT50|2160203|A|1219570|5555555555
78Z|099999999|0000001|PERD0|2151214|A|1512460|6666666666
78Z|099999999|0000001|RSAB0|2151214|A|1512460|6666666666
78Z|099999999|0000001|ANT32|2160219|A|0319000|6666666666
78Z|099999999|0000001|ANT09|2160218|D|0319000|6666666666
78Z|099999999|0000001|ABS10|2150615|D|0125350|6666666666

file2.txt

3333333311|ANT10
2222222222|ANT09
5555555555|ANT50
3333333333|ANT33
6666666666|ANT32
4444444444|ANT09

file1.txtの2列目と1列目がfile2.txtの4列目と8列目と一致する行を含む新しいファイルを作成する必要があります

結果は次のとおりです(順序は重要ではありません)

file3.txt

78Z|033333157|0000001|ANT10|2160208|A|1900460|3333333311
78Z|696931836|0000001|ANT09|2160203|A|1114450|2222222222
78Z|012344052|0000001|ANT50|2160203|A|1219570|5555555555
78Z|010041586|0000001|ANT33|2160119|A|1835100|3333333333
78Z|099999999|0000001|ANT32|2160219|A|0319000|6666666666
78Z|011512345|0000001|ANT09|2160218|D|0319230|4444444444
5
Miguel Angel
awk -F'|' 'NR==FNR{e[$2$1]=1;next};e[$4$8]' file2.txt file1.txt

最初にfile2を読み取って配列e[field2+field1]を設定し、次にfile1を読み取り、e[field4+field8]が設定されている場合は出力します。

またはフィールドを裏返します:

awk -F'|' 'NR==FNR{e[$1$2]=1;next};e[$8$4]' file2.txt file1.txt
5
Runium

質問にはタグが付けられています awk ですが、awkを使用してこれを行うしないでください。 coreutilsには、この種の場合に役立つjoinユーティリティがありますが、データがあると少し面倒です。

私はあなたのシェルがbashであり、GNU coreutilsであると仮定します。これは他のフレーバーで行うことができますが、おそらくデータの前処理/後処理がさらに必要になります。

難しい話は抜きにして:

join -t"|" -14 -22 -o"$(echo 1.{1..8} 2.1)" \
  <(sort -t"|" -k4 file1.txt) \
  <(sort -t"|" -k2 file2.txt) \
  | grep -Po ".*([\d]+)(?=\|\1$)"

joinは2つの入力ファイルを受け取り、-1および-2パラメーターで渡されたフィールドでそれらを結合します。 -tは、入力ファイルのカスタムフィールド区切り記号を示します。 joinでは、結合されるフィールドで入力ファイルをソートする必要があるため、2つの入力ファイルは、joinに渡される前にプロセス置換内でソートされます。 -oパラメータは、フィールドの出力方法を指定します。デフォルトでは、結合フィールド、その後にfile1の非結合フィールドが続き、その後にfile2の非結合フィールドが続くので、ファイル1のすべてのフィールド、ファイル2のフィールド1の順に指定する必要があることを指定する必要があります。

また、file1のフィールド8とfile1のフィールド1に結合する必要があります。これは、結合出力フィールド8と9が同じである場合、行のgreppingによってここで簡単に実装されます。 grep -Poで正規表現先読みを使用すると、これを実行してフィールド9を効果的に削除し、必要な出力を得ることができます。出力は次のとおりです。

78Z|696931836|0000001|ANT09|2160203|A|1114450|2222222222
78Z|011512345|0000001|ANT09|2160218|D|0319230|4444444444
78Z|033333157|0000001|ANT10|2160208|A|1900460|3333333311
78Z|099999999|0000001|ANT32|2160219|A|0319000|6666666666
78Z|010041586|0000001|ANT33|2160119|A|1835100|3333333333
78Z|012344052|0000001|ANT50|2160203|A|1219570|5555555555
4
Digital Trauma

より単純です。file2では、同じ最初のフィールドを2回指定することは許可されていません。

awk -F'|' 'FNR == NR { key[$1] = $2; next } $8 in key && key[$8] == $4' file2.txt file1.txt
3
Wildcard

試す

_awk 'BEGIN { FS="|"}
     FNR == NR { key[$2 $1]=NR }
     FNR > NR { k=$3 $8 ;if (k in key)  print ;} ' file2.txt file1.txt
_

どこ

  • _BEGIN { FS="|"}_ awに_|_を区切り記号として使用するように指示します(コマンドラインで_-F\|_を使用できます)
  • _FNR == NR { key[$2 $1]=NR }_ファイルのキーを記憶(file2.txtの場合)
  • FNR > NR { k=$4 $8 ;if (k in key) print ;}ハッシュリストのキーの場合、それを出力します

編集:あなたは3番目のファイルに言及し、4番目に参加します。

2
Archemar