尝试以下针对 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
EDIT 添加打印整行的版本(请参阅 cmets)。我在保存行的位置添加了另一个具有相同键的数组,并在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(参见 cmets)添加一个使用相同键处理多行的版本。基本上我加入所有条目而不是只保存一个,将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