首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >awk比较三个文件中的列,并打印与NA前缀不匹配的列及其内容

awk比较三个文件中的列,并打印与NA前缀不匹配的列及其内容
EN

Stack Overflow用户
提问于 2020-11-12 10:14:56
回答 2查看 40关注 0票数 3

您好,我有一个问题来解决三个文件的比较以获得所需的输出,其中file1列$2与file2列$4以及file3列$2进行比较,其中结果是它将附加到输出文件名file1加上将打印来自file1的不匹配列以及添加的NA以反映其余列,以保持它们的节奏性/一致性

file1

代码语言:javascript
复制
4 FIX VAL1 32254720
0 AA SILO_T 4294967290
16 RS SILO 2684560000
3 DD SILO_A 1041824000
2 BB SILO_B 4294729600

file2

代码语言:javascript
复制
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

代码语言:javascript
复制
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

输出应为:

代码语言:javascript
复制
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

部分工作的代码

代码语言:javascript
复制
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进行下一次比较来完成事情以获得所需的输出,如果提供的解决方案将与解释,这样我就可以充分理解如何在需要交换列号的情况下,在未来需要另一个需要比较的情况下,感谢您的帮助,如何扩展当前的代码或编写它更简单

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-12 14:16:03

您可以使用以下awk脚本:

代码语言:javascript
复制
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)
}

然后使用它作为:

代码语言:javascript
复制
awk -f mergeall.awk file2 file3 file1 | column -t
代码语言:javascript
复制
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

票数 3
EN

Stack Overflow用户

发布于 2020-11-12 15:01:55

从@anubhava先生的解决方案中获得灵感,在这里添加了一个更通用的解决方案,其中NA值将根据输入文件的字段数量来创建,我们不需要对其进行硬编码。您可以尝试使用GNU awk编写和测试下面的示例吗?

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64796946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档