N 個のファイルに対して一般化された次のソリューションを試してください。最初のファイルのデータを の値でハッシュに保存し1
、次のファイルからヒットするたびにその値を増やします。最後に、各キーの値が処理されたファイルの数と同じかどうかを比較し、一致するものだけを出力します。
awk '
FNR == NR { arr[$1,$2] = 1; next }
{ if ( arr[$1,$2] ) { arr[$1,$2]++ } }
END {
for ( key in arr ) {
if ( arr[key] != ARGC - 1 ) { continue }
split( key, key_arr, SUBSEP )
printf "%s %s\n", key_arr[1], key_arr[2]
}
}
' file{1..3}
次の結果が得られます。
"xxx" 0
"aba" 0
編集して、行全体を印刷するバージョンを追加します (コメントを参照)。行を保存する場所と同じキーを持つ別の配列を追加し、printf
関数でも使用します。古いコードをコメントのままにしました。
awk '
##FNR == NR { arr[$1,$2] = 1; next }
FNR == NR { arr[$1,$2] = 1; line[$1,$2] = $0; next }
{ if ( arr[$1,$2] ) { arr[$1,$2]++ } }
END {
for ( key in arr ) {
if ( arr[key] != ARGC - 1 ) { continue }
##split( key, key_arr, SUBSEP )
##printf "%s %s\n", key_arr[1], key_arr[2]
printf "%s\n", line[ key ]
}
}
' file{1..3}
NEW EDIT (コメントを参照) を使用して、同じキーで複数の行を処理するバージョンを追加します。基本的に、1 つだけを保存する代わりにすべてのエントリを結合し、 で変更line[$1,$2] = $0
しline[$1,$2] = line[$1,$2] ( line[$1,$2] ? SUBSEP : "" ) $0
ます。印刷時に、セパレーター(SUBSEP
変数)を使用して逆分割を行い、各エントリを印刷します。
awk '
FNR == NR {
arr[$1,$2] = 1
line[$1,$2] = line[$1,$2] ( line[$1,$2] ? SUBSEP : "" ) $0
next
}
FNR == 1 { delete found }
{ if ( arr[$1,$2] && ! found[$1,$2] ) { arr[$1,$2]++; found[$1,$2] = 1 } }
END {
num_files = ARGC -1
for ( key in arr ) {
if ( arr[key] < num_files ) { continue }
split( line[ key ], line_arr, SUBSEP )
for ( i = 1; i <= length( line_arr ); i++ ) {
printf "%s\n", line_arr[ i ]
}
}
}
' file{1..3}
問題の新しいデータを編集すると、次のようになります。
"xxx" 0 0
"aba" 0 0
"aba" 0 0 1