首页 > 解决方案 > 如何使用 awk 从两个文件中找出公共列及其记录

问题描述

我有两个文件:

文件 1:

id|name|address|country
1|abc|efg|xyz
2|asd|dfg|uio

文件 2(仅标题):

id|name|country

现在,我想要一个像这样的输出:

输出:

id|name|country
1|abc|xyz
2|asd|uio

基本上,我有一个用户记录文件(file1)和一个头文件(file2)。现在,我只想提取那些(file1)列与头文件中的列匹配的记录。

我想使用 awk 或 bash 来做到这一点。

我尝试使用:

awk 'BEGIN { OFS="..."} FNR==NR { a[(FNR"")] = $0; next } { print a[(FNR"")], $0 > "test.txt"}' header.txt file.txt

并且不知道下一步该做什么。

谢谢你

标签: bashunixawkgawk

解决方案


以下awk可能对您有所帮助。

awk -F"|" 'FNR==NR{for(i=1;i<=NF;i++){a[$i]};next} FNR==1 && FNR!=NR{for(j=1;j<=NF;j++){if($j in a){b[++p]=j}}} {for(o=1;o<=p;o++){printf("%s%s",$b[o],o==p?ORS:OFS)}}' OFS="|" File2  File1

现在也添加非单线形式的解决方案。

awk -F"|" '
FNR==NR{
   for(i=1;i<=NF;i++){
     a[$i]};
   next}
FNR==1 && FNR!=NR{
   for(j=1;j<=NF;j++){
     if($j in a){ b[++p]=j }}
}
{
   for(o=1;o<=p;o++){
     printf("%s%s",$b[o],o==p?ORS:OFS)}
}
' OFS="|" File2  File1

Ed Morton 编辑:FWIW 这是用正常缩进/间距和几个更有意义的变量名编写的相同脚本:

BEGIN { FS=OFS="|" }
NR==FNR {
    for (i=1; i<=NF; i++) {
        names[$i]
    }
    next
}
FNR==1 {
    for (i=1; i<=NF; i++) {
        if ($i in names) {
            f[++numFlds] = i
        }
    }
}
{
    for (i=1; i<=numFlds; i++) {
        printf "%s%s", $(f[i]), (i<numFlds ? OFS : ORS)
    }
}

推荐阅读