awk 比较三个文件中的列并打印不匹配的带有 NA 前缀的列及其内容
awk compare columns in three files and print match non match with NA prefix along with their content
嗨,我有一个问题要解决比较三个文件以获得所需的输出,
其中 file1 列 $2 与 file2 列 $4 以及 file3 列 $2 进行比较 其中是
结果它将附加到 file1 的输出文件名加上将从 file1 打印不匹配的列
连同添加的 NA 以反映剩余的列以保持它们的完整/一致
文件 1
4 FIX VAL1 32254720
0 AA SILO_T 4294967290
16 RS SILO 2684560000
3 DD SILO_A 1041824000
2 BB SILO_B 4294729600
文件2
377 le377 4 FIX cell 0x
514 le514 3 DD cell 0c
0 le0 2 BB cell 2a
516 le516 0 AA cell 8c
文件 3
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[]=[=14=];next}; \
{printf FILENAME "%s %s %s %s %s %s\n","",,,,, (( in a)?a[]: "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[] = [=10=]
next
}
ARGIND == 2 { # while processing 2nd file in arguments
map[] = ( in map ? map[] OFS : "") [=10=]
next
}
{ # while processing 3rd file in arguments
print FILENAME, [=10=], ( in map ? map[] : 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 先生的解决方案中汲取灵感,添加一些更通用的解决方案,其中 NA
值将根据 Input_file 的字段数创建,我们不需要对其进行硬编码。您能否尝试使用 GNU awk
.
中显示的示例进行跟踪、编写和测试
awk '
ARGIND<=2{
fill[ARGIND]=(fill[ARGIND]>NF?fill[ARGIND]:NF)
}
ARGIND == 1 {
map[] = [=10=]
next
}
ARGIND == 2 {
map[] = ( in map ? map[] OFS : "") [=10=]
next
}
ARGIND == 3 && file==""{ file = FILENAME }
{
if(!arr[]++){ ind[++count] = }
val[]=[=10=]
}
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
嗨,我有一个问题要解决比较三个文件以获得所需的输出, 其中 file1 列 $2 与 file2 列 $4 以及 file3 列 $2 进行比较 其中是 结果它将附加到 file1 的输出文件名加上将从 file1 打印不匹配的列 连同添加的 NA 以反映剩余的列以保持它们的完整/一致
文件 1
4 FIX VAL1 32254720
0 AA SILO_T 4294967290
16 RS SILO 2684560000
3 DD SILO_A 1041824000
2 BB SILO_B 4294729600
文件2
377 le377 4 FIX cell 0x
514 le514 3 DD cell 0c
0 le0 2 BB cell 2a
516 le516 0 AA cell 8c
文件 3
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[]=[=14=];next}; \
{printf FILENAME "%s %s %s %s %s %s\n","",,,,, (( in a)?a[]: "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[] = [=10=]
next
}
ARGIND == 2 { # while processing 2nd file in arguments
map[] = ( in map ? map[] OFS : "") [=10=]
next
}
{ # while processing 3rd file in arguments
print FILENAME, [=10=], ( in map ? map[] : 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 先生的解决方案中汲取灵感,添加一些更通用的解决方案,其中 NA
值将根据 Input_file 的字段数创建,我们不需要对其进行硬编码。您能否尝试使用 GNU awk
.
awk '
ARGIND<=2{
fill[ARGIND]=(fill[ARGIND]>NF?fill[ARGIND]:NF)
}
ARGIND == 1 {
map[] = [=10=]
next
}
ARGIND == 2 {
map[] = ( in map ? map[] OFS : "") [=10=]
next
}
ARGIND == 3 && file==""{ file = FILENAME }
{
if(!arr[]++){ ind[++count] = }
val[]=[=10=]
}
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