hi我有一个问题要解决三个文件的比较以获得所需的输出,其中file1列$2与file2列$4以及file3列$2进行比较,其中它将附加到文件1的输出文件名的结果,加上将打印文件1中不匹配的列以及添加的NA,以反映剩余的列,使它们保持一致/一致的
file1
4 FIX VAL1 32254720
0 AA SILO_T 4294967290
16 RS SILO 2684560000
3 DD SILO_A 1041824000
2 BB SILO_B 4294729600
file2
377 le377 4 FIX cell 0x
514 le514 3 DD cell 0c
0 le0 2 BB cell 2a
516 le516 0 AA cell 8c
file3
3 DD SILO_A 100 on 0 yes
2 BB SILO_B 400 on 0 no
0 AA SILO_T 3 on 0 yes
4 FIX VAL1 30 on 0 no
输出应该是:
file1 4 FIX VAL1 32254720 377 le377 4 FIX cell 0x 4 FIX 30 on 0 no
file1 0 AA SILO_T 4294967290 516 le516 AA cell 8c 0 AA 3 on 0 yes
file1 16 RS SILO 2684560000 NA NA NA NA NA NA NA NA NA NA NA
file1 3 DD SILO_A 1041824000 514 le514 3 DD cell 0c DD 100 on 0 yes
file1 2 BB SILO_B 4294729600 0 le0 2 BB cell 2a BB 400 on 0 no
部分工作代码
awk 'FNR==NR{a[$3]=$0;next};
{printf FILENAME "%s %s %s %s %s %sn","",$1,$2,$3,$4,$5 (($1 in a)?a[$1]: "NA NA NA NA NA NA")}' file2 file1
file1 4 FIX VAL1 32254720 377 le377 4 FIX cell 0x
file1 0 AA SILO_T 4294967290 516 le516 0 AA cell 8c
file1 16 RS SILO 2684560000 NA NA NA NA NA NA
file1 3 DD SILO_A 1041824000 514 le514 3 DD cell 0c
file1 2 BB SILO_B 4294729600 0 le0 2 BB cell 2a
我不知道如何传递file3进行下一次比较,以完成所需的输出,如果提供的解决方案中有解释,我会很高兴,这样我就可以完全理解在需要的情况下如何交换列号,以防将来需要另一次比较。谢谢你的帮助,如何扩展当前代码或编写更简单的
您可以使用以下awk
脚本:
cat mergeall.php
BEGIN {
fill = "NA NA NA NA NA NA NA NA NA NA NA NA NA"
}
ARGIND == 1 { # while processing 1st file in arguments
map[$4] = $0
next
}
ARGIND == 2 { # while processing 2nd file in arguments
map[$2] = ($2 in map ? map[$2] OFS : "") $0
next
}
{ # while processing 3rd file in arguments
print FILENAME, $0, ($2 in map ? map[$2] : fill)
}
然后将其用作:
awk -f mergeall.awk file2 file3 file1 | column -t
file1 4 FIX VAL1 32254720 377 le377 4 FIX cell 0x 4 FIX VAL1 30 on 0 no
file1 0 AA SILO_T 4294967290 516 le516 0 AA cell 8c 0 AA SILO_T 3 on 0 yes
file1 16 RS SILO 2684560000 NA NA NA NA NA NA NA NA NA NA NA NA NA
file1 3 DD SILO_A 1041824000 514 le514 3 DD cell 0c 3 DD SILO_A 100 on 0 yes
file1 2 BB SILO_B 4294729600 0 le0 2 BB cell 2a 2 BB SILO_B 400 on 0 no
请注意,我们按以下顺序输入文件:file2 file3 file1
从@anubhava sir的解决方案中获得灵感,添加了一个更通用的解决方案,其中NA
值将根据Input_file的字段数创建,我们不需要对其进行硬编码。请您尝试以下内容,并使用GNUawk
中显示的示例进行编写和测试。
awk '
ARGIND<=2{
fill[ARGIND]=(fill[ARGIND]>NF?fill[ARGIND]:NF)
}
ARGIND == 1 {
map[$4] = $0
next
}
ARGIND == 2 {
map[$2] = ($2 in map ? map[$2] OFS : "") $0
next
}
ARGIND == 3 && file==""{ file = FILENAME }
{
if(!arr[$2]++){ ind[++count] = $2 }
val[$2]=$0
}
END{
for(j=1;j<=ARGIND;j++){
s=sprintf("%"fill[j]"s","");gsub(/ /,"NA ",s);sub(/ +$/,"",s)
fillVal=(fillVal?fillVal OFS:"")s
s=""
}
for(i=1;i<=count;i++){
print file, val[ind[i]], (ind[i] in map ? map[ind[i]] : fillVal)
}
}' Input_file2 Input_file3 Input_file1