結合可能な各 f1 レコードが f2 で使用可能な最初の一致可能レコードに一度だけ結合されるように、f1 を f2 に結合します。

結合可能な各 f1 レコードが f2 で使用可能な最初の一致可能レコードに一度だけ結合されるように、f1 を f2 に結合します。

列 1 と列 2 に基づいてソートされた次の 2 つのファイルがあるとします。

f1:

card1,value1,f1c11,f1c12
card2,value2,f1c21,f1c22
card3,value3,f1c31,f1c32
card4,value4,f1c41,f1c42
card4,value4,f1c411,f1c412
card4,value41,f1c421,f1c422
card5,vaule5,f1c51,f1c52

f2:

card,value2,f2c1,f2c2
card2,value,f2c21,f2c22
card2,value2,f2c211,f2c212
card2,value2,f2c221,f2c222
card3,value3,f2c31,f2c32
card4,value4,f2c41,f2c42
card4,value4,f2c411,f2c412
card5,vaule5,f2c51,f2c52
card6,vaule6,f2c61,f2c62
card7,vaule5,f2c71,f2c72

必要なもの:f1をf2に結合して、結合可能な各f1レコードをf2で使用可能な最初の一致可能レコードに1回だけ結合するようにします。

card2,value2,f1c21,f1c22,f2c211,f2c212
card3,value3,f1c31,f1c32,f2c31,f2c32
card4,value4,f1c41,f1c42,f2c41,f2c42
card4,value4,f1c411,f1c412,f2c41,f2c42
card5,vaule5,f1c51,f1c52,f2c51,f2c52

詳細なマッチングロジックは次のとおりです。

  • f1のカード1、値1(ライン1)f2で一致する項目が表示されない - >無視
  • f1(ライン2)のcard2、value2は、f2(ライン3)の最初の一致を確認します。この一致の後、f1 行 2 と f2 行 3 は使用できなくなります。
  • f1(ライン3)のcard3、value3は、f2(ライン5)の最初の一致を確認します。この一致の後、f1 行 3 および f2 行 5 は使用できなくなります。
  • f1(ライン4)のcard4、value4は、f2(ライン6)の最初の一致を確認します。この一致の後、f1 行 4 と f2 行 6 は使用できなくなります。
  • f1(ライン5)のcard4、value4は、f2(ライン7)の最初の一致を確認します。この一致の後、f1 行 5 および f2 行 7 は使用できなくなります。
  • f1のカード4、値4(行6)は、f2で一致するものを見つけることができません。 ->無視
  • f1(ライン7)のcard5、value5は、f2(ライン8)の最初の一致を確認します。この一致の後、f1ライン7及びf2ライン8はもはや使用できなくなる。

ベストアンサー1

BashとGNU awkを使ったスクリプト。これは入力ファイルの1つをソートする必要はありません。出力は、引数として渡された最初のファイルの順序で行われます。

4番目の出力ラインに問題があるようです。 f2カード4最初の行が再び繰り返されます。

2番目のファイルの内容全体はRow配列に格納され、行番号は入力された順序でList形式でMapに保存されます。

その後、最初のファイルは、何も残らないまで使用しているすべてのマッピングエントリを削除します。

#! /bin/bash --

#:: firstJoin: join only the first records with matching keys.

Join () {

    local AWK='
BEGIN { FS = ","; OFS = ","; reClip = "^[^,]*,[^,]*,"; }
#.. Store input from first file.
function Store (key, tx, Local) {
    sub (reClip, "", tx);
    Row[FNR] = tx;
    Map[key] = Map[key] FNR FS FS;
}
#.. Pair second file with first available.
function Pair (key, tx, Local) {
    if (! (key in Map) || (Map[key] == "")) return;
    printf ("%s%s%s\n", tx, OFS, Row[0+Map[key]]);
    sub (reClip, "", Map[key]);
}
FNR == NR { Store( $1 FS $2, $0); next; }
{ Pair( $1 FS $2, $0); }
'   
    awk -f <( printf '%s' "${AWK}" ) "${2}" "${1}"
}   
    
    Join "${1}" "${2}"

テストショット:

Paul--) ./firstJoin  JoinF1 JoinF2
card2,value2,f1c21,f1c22,f2c211,f2c212
card3,value3,f1c31,f1c32,f2c31,f2c32
card4,value4,f1c41,f1c42,f2c41,f2c42
card4,value4,f1c411,f1c412,f2c411,f2c412
card5,vaule5,f1c51,f1c52,f2c51,f2c52
Paul--) 

おすすめ記事