AWK - 比较两个 1-column 文件以匹配字符串,然后写入一个包含更新信息的文件

AWK - compare two 1-column files for matching strings then write a file with updated info

我在比较两个不同编号的文件时遇到问题。行并使用文件中的信息来更新另一个。我尝试了在网上找到的各种关键示例,但 none 似乎有效。

希望你能帮我解决这个问题。

我有两个文件:

$ cat 1.txt
>01234
NNNNNNNNAAAAAANNNNNNAAAAANNNNAAAAANNNNAA
>17321
SSSSSSKKKKKKLLLLLIIIIIIMMMMMMNNNNNNAAAA
>13920
ZZZZZZZYYYYYYYAAAAAAABBBBBBBCCCCNNNNNNNNNN
...
...
(>1000 lines)


$ cat 2.txt
hbcd/efgh/z-01234/2000
hbcd/efgh/zw-11000/2000
hbcd/efgh/t-13290/2000
...
...
(<1000 lines)

我的目的是更新文件 1.txt,其中包含更新的行,但也要保留文件 2.txt 中不匹配的行,因此可以另存为新文件,如下所示:

$ cat 3.txt
>abcd/efgh/z-01234/2000
NNNNNNNNAAAAAANNNNNNAAAAANNNNAAAAANNNNAA
>17321
SSSSSSKKKKKKLLLLLIIIIIIMMMMMMNNNNNNAAAA
>abcd/efgh/t-13290/2000
ZZZZZZZYYYYYYYAAAAAAABBBBBBBCCCCNNNNNNNNNN
...
...

我试过这样的事情: awk 'NR==FNR{a[[=38=]]=[=38=];next}{a[]=[=38=]}END{for (i in a) print a[i]}' 1.txt 2.txt > 3.txt

或者像这样(根据1.txt中的子串搜索): awk 'NR==FNR{a[substr([=39=],2,5)]=[=39=];next}{a[]=[=39=]}END{for (i in a) print a[i]}' 2.txt 1.txt > 3.txt

但是我在输出文件中混淆了行,像这样(或者甚至没有来自 2.txt 的行):

01234 17321 SSSSSSKKKKKKLLLLLIIIIIIMMMMMMNNNNNNAAAA abcd/efgh/t-13290/2000 NNNNNNNNAAAAAANNNNNNAAAAANNNNAAAAANNNNAA ZZZZZZZYYYYYYYAAAAAAABBBBBBBCCCCNNNNNNNNNN

我已经很长时间没有使用 awk 了,我不确定数组和键是如何工作的。

更新: 我试图编写一个 awk 脚本来执行上述操作。检查它们的条件有效,但不知何故,我仍然无法从 1.txt 中编写与 2.txt.

中的行不匹配的行
BEGIN{
    i = 0;
    j = 0;
    k = 0;
    maxi = 0;
    maxj = 0;
    maxk = 0;
    FS = "\/";
}

FILENAME == ARGV[1]{
    header1=substr([=12=],1,1);
    if(header1==">"){
        ++maxi;
        seqcode1[maxi]=substr([=12=],2,5);
#       printf("%s\n",seqcode1[maxi]);
    }
    else if(header1!=">"){
        ++maxk;
        seqFASTA[maxk]=[=12=];
#       print seqFASTA[maxk];
    }
}

FILENAME == ARGV[2]{
    header2=substr([=12=],1,1);
    if(header2=="h"){
        ++maxj;
        wholename[maxj]=[=12=];
        seqcode2[maxj]=substr(,4,5);
#       printf("%s\n",seqcode2[maxj]);
    }
}

END{
    for(i=1;i<=maxi=maxk;i++){
      for(j=1;j<=maxj;j++){
        if(seqcode1[i] == seqcode2[j]) {
            printf("%s %s %s\n",seqcode1[i],seqcode2[j],wholename[j]);
        }
        else
          print seqcode1[i];
          print seqFASTA[k];
        }
    }
}

我认为问题可能在于声明 seqFASTA,但我不确定在哪里。

非常感谢! M.

我假设 139201.txt 中应该是 13290

$ awk 'NR==FNR{split([=10=], a, "/"); sub(/^[^-]+-/, "", a[3]); map[a[3]]=[=10=]; next}
       (k=substr([=10=], 2)) in map{[=10=] = ">" map[k]} 1' 2.txt 1.txt
>hbcd/efgh/z-01234/2000
NNNNNNNNAAAAAANNNNNNAAAAANNNNAAAAANNNNAA
>17321
SSSSSSKKKKKKLLLLLIIIIIIMMMMMMNNNNNNAAAA
>hbcd/efgh/t-13290/2000
ZZZZZZZYYYYYYYAAAAAAABBBBBBBCCCCNNNNNNNNNN

以下是一些替代解决方案:

# with GNU awk
awk 'NR==FNR{match([=11=], /-([0-9]+)/, a); map[a[1]]=[=11=]; next}
     (k=substr([=11=], 2)) in map{[=11=] = ">" map[k]} 1' 2.txt 1.txt

# assuming '/' and '-' will always be similar to given sample
awk -F'[/-]' 'NR==FNR{map[]=">"[=11=]; next}
               in map{[=11=] = map[]} 1' 2.txt FS='>' 1.txt