配列に重複したインデックス値があります。

配列に重複したインデックス値があります。

次の文書が与えられた場合:

ファイル1:

7997,1
7997,2
7997,3
5114,1
5114,2

ファイル2:

7997,52,
5114,12,
4221,52,

file2awkのデータと比較する値で最初の列をインデックスに、2番目の列を値として最初のファイルから配列を作成するにはどうすればよいですか?

このような:

cat file1 file2 | awk -F, '{if(NF==2){arr[$1]=$2}else{if(arr[$1]){print arr[$1]","$0}}}'

希望の出力は次のとおりです。

1,2,3,7997,52
1,2,5114,12

ベストアンサー1

1つの方法は次のとおりです。

$ awk -F, -vOFS=, 'NR==FNR{a[$1]=a[$1]","$2; next} 
                   ($1 in a){print a[$1],$0}' file1 file2 | 
    sed 's/^,\(.*\),$/\1/'
1,2,3,7997,52
1,2,5114,12

説明する

  • -F, -vOFS=,:入力フィールド区切り記号(-F)と出力フィールド区切り文字(実行時-vOFSに印刷される各値の間に挿入される文字列print $1,$2)をコンマに設定します。

  • NR==FNR{a[$1]=a[$1]","$2; next}FNR行番号です現在のファイルNRは入力行番号です。読み込む 2 つのファイルが与えられると、awkこれらの変数は最初のファイルを読み取るときにのみ同じです。したがって、最初のブロックは、NR==FNR{}最初のファイルを読み取るときにのみ実行されます。

    このブロックのコードは、a最初のフィールドでインデックス付けされた配列を作成します。ブロックが実行されるたびに、配列のインデックスに格納されている項目にコンマと2番目のフィールドの値が追加されます$1next最初のファイルの2番目のブロックが実行されないように、スクリプトの実行を続行せずに次の入力行にジャンプします。

    最初の実行はa[$1]空であるため、配列の先頭に追加のコンマが追加されます。sed最後の項目として削除します。

  • ($1 in a){print a[$1],$0}:これは2番目のファイルにあります。行の最初のフィールドが配列のインデックスである場合は、現在のa行()の対応するインデックスに関連する値を印刷します。a$0

  • sed 's/^,\(.*\),$/\1/':行の最初のカンマ()と一致し、括弧を使用して^,最後のコンマ()\(.*\),$を除くすべての項目をキャプチャします。次に、コンテンツ全体をキャプチャされたパターン(\1)に置き換えます。その結果、各行の最初と最後のコンマのみが削除されます。これは、スクリプトが行の先頭に追加する追加のコンマawkも削除することですfile2。目的の出力にも表示されないからです。

おすすめ記事