2番目の「Key-Value」ファイルの対応するキーにマップされていないデータフィールドを含む1つの「Key-Value List」ファイルで行を見つけます。

2番目の「Key-Value」ファイルの対応するキーにマップされていないデータフィールドを含む1つの「Key-Value List」ファイルで行を見つけます。

2つのファイルがあります。 1つのファイルには、1行に少なくとも2つのフィールド(ユーザー名、年齢、およびそのフィールドのさまざまな「フルーツ」数)が含まれ、他のファイルには常に1行に2つのフィールド(ユーザー名と「フルーツ」)が含まれています。されています。私はそれらをfile1「データベース」ファイルとfile2「マッピング」ファイルと呼びます。

file1各ユーザー名について、そのユーザーに対応する行に「fruit」が含まれていることを確認したいと思います。いいえこのユーザーにマップされましたfile2

例:

  • file1(このファイルの1行あたりの果物の数は可変です。)

    james,25,strawberry,rassberry,blueberry
    james,25,strawberry,rassberry,mango
    james,26,blueberry
    james,27,pineapple
    erik,30,strawberry,rassberry,mango
    
  • file2:

    james,strawberry
    james,rassberry
    james,blueberry
    erik,blueberry
    erik,rassberry
    
  • 希望の出力:

    james,25,strawberry,rassberry,mango
    james,27,pineapple
    erik,30,strawberry,rassberry,mango
    

    この行は、ユーザーまたはユーザーとの接続を含まず、ユーザーまたはfile2ユーザーとの接続も含まないために選択されました。mangopineapplejamesstrawberrymangoerik

私のコードでは部分的な解決策しか得られません。以下で試しましたが、同じ行の他の列は確認されません。

awk 'BEGIN{FS=OFS=","}NR==FNR{a[$1]=$2;next}
{if (a[$1] && (a[$1]!=$3)){print $0, a[$1]}}' file2 file1

ベストアンサー1

awk -F, '
    !nxtfile{ join[$1]= (join[$1]==""?"": join[$1] FS) $2; next }
            { split(join[$1], tmp, ","); for(x in tmp) fruits[tmp[x]];
              for(i=3; i<=NF; i++) if(!($i in fruits)) { print; break }
            }
' file2 nxtfile=1 file1

最初のブロックでは入力を処理しています。ファイル2同じ結果を得るには、他の行のすべての果物を一緒にリンクします。名前そして、それをキーと値のペアで名前付き連想配列に保存します。参加する

2番目のブロックでは入力を処理しています。ファイル1配列内の最初に一致するフィールドの値を取得し、コンマ区切り文字を使用して一時配列に分割します。tmpその後、別の配列を再構成します。果物そして価値tmpキーとして使用される配列果物配列(つまり、tmp配列の値は次のとおりです。果物大量に)。

最後のステップは、> = 3番目のフィールドを最後まで繰り返し、そのフィールドが次の場所にあることを1つずつ確認することです。果物配列、一致しない最初のフィールドから行全体を印刷し、残りのフィールドを読み続ける必要がないため、ループを中断します。

おすすめ記事