awk 合并来自两个文件的信息(fasta 文件头)
awk combine info from two files (fasta file header)
我知道有很多类似的问题,我也看了很多。但我仍然无法让我的代码工作。有人可以帮我指出问题吗?谢谢!
(base) $ head Sample.pep2
>M00000032072 gene=G00000025773 seq_id=ChrM type=cds
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSRFGIY*
>M00000032073 gene=G00000025774 seq_id=ChrM type=cds
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSSIASMILGALAAMAQTKVKRPLAHSSIGHVGYIRTGFSCGTI
EGIQSLLIGIFIYALMTMDAFAIVSALRQTRVKYIADLGALAKTNPISAITFSITMFSYA
GIPPLAGFCSKFYLFFAALGCGAYFLAPVGVVTSVIGRWAAGRLPRISKFGGPKAVLRAP
$ head -n 3 mRNA.function
M00000032074 locus=g17091;makerName=TCONS_00021197.p2
M00000032073 Dbxref=MobiDBLite:mobidb-lite;locus=g17092;makerName=TCONS_00021198.p3
M00000032072 Dbxref=MobiDBLite:mobidb-lite;locus=g17093;makerName=TCONS_00021199.p1
我想要输出
>M00000032072 gene=G00000025773 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17093;makerName=TCONS_00021199.p1
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSRFGIY*
>M00000032073 gene=G00000025774 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17092;makerName=TCONS_00021198.p3
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSSIASMILGALAAMAQTKVKRPLAHSSIGHVGYIRTGFSCGTI
EGIQSLLIGIFIYALMTMDAFAIVSALRQTRVKYIADLGALAKTNPISAITFSITMFSYA
GIPPLAGFCSKFYLFFAALGCGAYFLAPVGVVTSVIGRWAAGRLPRISKFGGPKAVLRAP
我的命令是awk 'NR==FNR{id[]=; next} /^>/ {print [=12=]=[=12=],id[]}' mRNA.function Sample.pep2
。但是还是不行。。。不知道哪里错了。。。
当前代码很接近,只需要 a) 将第一个字段 (Sample.pep2
) 与相应的数组条目(如果存在)匹配,b) 确保我们打印所有输入行:
awk 'NR==FNR{id[]=; next} /^>/ {key=substr(,2); if (key in id) [=10=]=[=10=] OFS id[key]} 1' mRNA.function Sample.pep2
这会生成:
>M00000032072 gene=G00000025773 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17093;makerName=TCONS_00021199.p1
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSRFGIY*
>M00000032073 gene=G00000025774 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17092;makerName=TCONS_00021198.p3
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSSIASMILGALAAMAQTKVKRPLAHSSIGHVGYIRTGFSCGTI
EGIQSLLIGIFIYALMTMDAFAIVSALRQTRVKYIADLGALAKTNPISAITFSITMFSYA
GIPPLAGFCSKFYLFFAALGCGAYFLAPVGVVTSVIGRWAAGRLPRISKFGGPKAVLRAP
这是一个 perl 解决方案。
perl -lpe 'BEGIN { %id_to_function = map { /^(\S+)\s+(.*)/ } `cat mRNA.function`; } s{^>(\S+)(.*)}{> $id_to_function{}};' sample.pep2
在读取 fasta 文件之前,代码执行 BEGIN { ... }
块。在那里,带有 id 和函数的文件被读入哈希 %id_to_function
.
在代码的主要 body 中,替换运算符 s{...}{...}
使用散列查找 $id_to_function{}
.
将相应 id 的函数附加到 fasta header
</code> 和 <code>
是第一个和第二个捕获组,相应地,它们在前面的正则表达式中用括号捕获:^>(\S+)(.*)
.
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-p
:一次循环输入一行,默认分配给 $_
。在每次循环迭代后添加 print $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches
perldoc perlrequick
: Perl regular expressions quick start
awk '
NR==FNR {a[">"]=}
NR!=FNR && a[] != "" {[=10=]=[=10=]" "a[]}
NR!=FNR' mRNA.function Sample.pep2
你在阵列方面走在了正确的轨道上。在 file2 中,您需要检查该行是否以 file1 中的匹配名称开头,然后再附加其数据。这就是 a[] != ""
所做的。
此示例假设第一个文件只有两个字段(数据中没有空格)。如果有空格我可以post编辑。
我知道有很多类似的问题,我也看了很多。但我仍然无法让我的代码工作。有人可以帮我指出问题吗?谢谢!
(base) $ head Sample.pep2
>M00000032072 gene=G00000025773 seq_id=ChrM type=cds
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSRFGIY*
>M00000032073 gene=G00000025774 seq_id=ChrM type=cds
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSSIASMILGALAAMAQTKVKRPLAHSSIGHVGYIRTGFSCGTI
EGIQSLLIGIFIYALMTMDAFAIVSALRQTRVKYIADLGALAKTNPISAITFSITMFSYA
GIPPLAGFCSKFYLFFAALGCGAYFLAPVGVVTSVIGRWAAGRLPRISKFGGPKAVLRAP
$ head -n 3 mRNA.function
M00000032074 locus=g17091;makerName=TCONS_00021197.p2
M00000032073 Dbxref=MobiDBLite:mobidb-lite;locus=g17092;makerName=TCONS_00021198.p3
M00000032072 Dbxref=MobiDBLite:mobidb-lite;locus=g17093;makerName=TCONS_00021199.p1
我想要输出
>M00000032072 gene=G00000025773 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17093;makerName=TCONS_00021199.p1
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSRFGIY*
>M00000032073 gene=G00000025774 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17092;makerName=TCONS_00021198.p3
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSSIASMILGALAAMAQTKVKRPLAHSSIGHVGYIRTGFSCGTI
EGIQSLLIGIFIYALMTMDAFAIVSALRQTRVKYIADLGALAKTNPISAITFSITMFSYA
GIPPLAGFCSKFYLFFAALGCGAYFLAPVGVVTSVIGRWAAGRLPRISKFGGPKAVLRAP
我的命令是awk 'NR==FNR{id[]=; next} /^>/ {print [=12=]=[=12=],id[]}' mRNA.function Sample.pep2
。但是还是不行。。。不知道哪里错了。。。
当前代码很接近,只需要 a) 将第一个字段 (Sample.pep2
) 与相应的数组条目(如果存在)匹配,b) 确保我们打印所有输入行:
awk 'NR==FNR{id[]=; next} /^>/ {key=substr(,2); if (key in id) [=10=]=[=10=] OFS id[key]} 1' mRNA.function Sample.pep2
这会生成:
>M00000032072 gene=G00000025773 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17093;makerName=TCONS_00021199.p1
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSRFGIY*
>M00000032073 gene=G00000025774 seq_id=ChrM type=cds Dbxref=MobiDBLite:mobidb-lite;locus=g17092;makerName=TCONS_00021198.p3
MFKQNPSPGWKECPPSSDKEGTTPERLDEGREMRRGKEKAFGDREISFLLHRKRRRPRIA
YGACYLKGARFFDRGAMIAGASPRSARWPIGIAACGLCLPIRIIIKNSGSARESAGNNRK
EGVHVAAAPAPLLSQWGSSIASMILGALAAMAQTKVKRPLAHSSIGHVGYIRTGFSCGTI
EGIQSLLIGIFIYALMTMDAFAIVSALRQTRVKYIADLGALAKTNPISAITFSITMFSYA
GIPPLAGFCSKFYLFFAALGCGAYFLAPVGVVTSVIGRWAAGRLPRISKFGGPKAVLRAP
这是一个 perl 解决方案。
perl -lpe 'BEGIN { %id_to_function = map { /^(\S+)\s+(.*)/ } `cat mRNA.function`; } s{^>(\S+)(.*)}{> $id_to_function{}};' sample.pep2
在读取 fasta 文件之前,代码执行 BEGIN { ... }
块。在那里,带有 id 和函数的文件被读入哈希 %id_to_function
.
在代码的主要 body 中,替换运算符 s{...}{...}
使用散列查找 $id_to_function{}
.
将相应 id 的函数附加到 fasta header
</code> 和 <code>
是第一个和第二个捕获组,相应地,它们在前面的正则表达式中用括号捕获:^>(\S+)(.*)
.
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-p
:一次循环输入一行,默认分配给 $_
。在每次循环迭代后添加 print $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches
perldoc perlrequick
: Perl regular expressions quick start
awk '
NR==FNR {a[">"]=}
NR!=FNR && a[] != "" {[=10=]=[=10=]" "a[]}
NR!=FNR' mRNA.function Sample.pep2
你在阵列方面走在了正确的轨道上。在 file2 中,您需要检查该行是否以 file1 中的匹配名称开头,然后再附加其数据。这就是 a[] != ""
所做的。
此示例假设第一个文件只有两个字段(数据中没有空格)。如果有空格我可以post编辑。