如何解决awk比较三个文件中的列,并打印不匹配的NA前缀及其内容
您好,我有一个问题需要解决三个文件的比较以获得所需的输出, 其中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 %s\n","",$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先生的解决方案中汲取灵感,添加了一些通用的解决方案,其中将根据Input_file的字段数创建NA
值,而我们无需对其进行硬编码。您可以尝试使用GNU awk
中的示例跟踪,编写和测试示例。
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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。