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.
我假设 13920
在 1.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
我在比较两个不同编号的文件时遇到问题。行并使用文件中的信息来更新另一个。我尝试了在网上找到的各种关键示例,但 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.
我假设 13920
在 1.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