3个文件字符串匹配模式分隔文件中的模式awk

时间:2018-06-14 09:59:59

标签: bash perl text awk sed

我有3个文件:

文件1

NODE_2020   Cancer
NODE_2029   Thug
NODE_0902   Snap

文件2

NODE_2020   Mikro   
NODE_2029   Bold
NODE_0902   Mini

文件3

NODE_2020   Gold
NODE_2080   Damn
NODE_0900   Gueo

我需要在另外两个中搜索文件1的第一列:如果值匹配,则文件2的第2列和文件3的第2列将打印成单个文件;如果没有,将打印一个“NO MATCH”字符串作为回报。输出文件将如下所示:

Query   File1   File2   File3

NODE_2020   Cancer  Mikro   Gold    
NODE_2029   Thug    Bold    NO MATCH    
NODE_0902   Snap    Mini    NO MATCH

非常感谢awk / sed / perl解决方案。我坚持做的是使用文件1的第一列作为变量来查看其他2个文件中的 if 语句。

这是我尝试过的,使用文件1中的列并匹配到文件2中:

awk 'NR==FNR{a[NR]=$1;next} { print a[FNR],"\t", $2 }' file1 file2

它实际上适用于2个文件。不知道如何扩展到三个文件,并添加“NO MATCH”模式。

2 个答案:

答案 0 :(得分:3)

使用GNU awk实现真正的多维数组和ARGIND:

$ cat tst.awk
BEGIN { OFS="\t" }
(NR==FNR) || ($1 in vals) {
    vals[$1][ARGIND] = $2
}
END {
    printf "%s%s", "Query", OFS
    for (fileNr=1; fileNr<=ARGIND; fileNr++) {
        printf "%s%s", ARGV[fileNr], (fileNr<ARGIND ? OFS : ORS)
    }
    for (key in vals) {
        printf "%s%s", key, OFS
        for (fileNr=1; fileNr<=ARGIND; fileNr++) {
            val = (fileNr in vals[key] ? vals[key][fileNr] : "NO MATCH")
            printf "%s%s", val, (fileNr<ARGIND ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file1 file2 file3
Query   file1   file2   file3
NODE_2020       Cancer  Mikro   Gold
NODE_0902       Snap    Mini    NO MATCH
NODE_2029       Thug    Bold    NO MATCH

答案 1 :(得分:2)

您可以使用此awk

awk -v OFS='\t' 'function bval(p,q) {
    return ((p,q) in b ? b[p,q] : "NO MATCH")
}
FNR == NR {
   a[$1] = $2
   next
}
{
   b[FILENAME,$1] = $2
}
END {
   print "Query", ARGV[1], ARGV[2], ARGV[3]
   for (i in a)
      print i, a[i], bval(ARGV[2],i), bval(ARGV[3],i)
}' file{1,2,3}

Query   file1   file2   file3
NODE_2020   Cancer  Mikro   Gold
NODE_0902   Snap    Mini    NO MATCH
NODE_2029   Thug    Bold    NO MATCH