如果行以“>”开头并在其末尾添加模式的出现次数,则使用 awk 查找模式
using awk to find pattern if line starts with ">" and add at the end of it the number of occurences of the pattern
我一直在努力使用 awk 找出一种方法来找到相同的模式,并在它们的末尾添加一个标签,以显示它们在文件中出现的次数。
例如,如果Spiroplasma_culicicola出现了7次,那么在第一次出现的旁边写Spiroplasma_culicicola_1,在第二次出现的旁边写Spiroplasma_culicicola_2在第三次出现的旁边写Spiroplasma_culicicola_3 等等等等
但是我有一个如下所示的 fasta 文件:
>Spiroplasma_taiwanense
GKGVKYKNEKIIRKEGKAAGKMTTDVIADMLTRIRNANQRFHKEVVIPGSKVKLEIANIL
KKEGFIEDFKVADDFKKDITISLKYRGKTRVIKGLKRISKPGLRVYSHATEIPQVLNGLG
IAIVSTSHGIMTDKEARQQNAGGEVLAFVW
>Spiroplasma_diminutum
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
KSKILRGDVVKVIAGSHKGKIGPVVKLSKDKKRVYVEGIVAIK-HAKPSQTDQEGGIREI
PAGVDISNVSLVDPKVKDSATRVGYKIADGKKVRIAKKSGSEVK-MIQNESRLKVADNSG
>Spiroplasma_diminutum
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
...
所以我想添加 "tag",该数字仅显示在 headers 旁边!因此上面的文件应该是这样的:
>Spiroplasma_taiwanense_1
GKGVKYKNEKIIRKEGKAAGKMTTDVIADMLTRIRNANQRFHKEVVIPGSKVKLEIANIL
KKEGFIEDFKVADDFKKDITISLKYRGKTRVIKGLKRISKPGLRVYSHATEIPQVLNGLG
IAIVSTSHGIMTDKEARQQNAGGEVLAFVW
>Spiroplasma_diminutum_1
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
KSKILRGDVVKVIAGSHKGKIGPVVKLSKDKKRVYVEGIVAIK-HAKPSQTDQEGGIREI
PAGVDISNVSLVDPKVKDSATRVGYKIADGKKVRIAKKSGSEVK-MIQNESRLKVADNSG
>Spiroplasma_diminutum_2
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
...
根据之前回答的问题,我认为我应该使用 awk,像这样:
awk '$1 ~ /^>/ {gsub(" ", "", $0);一个[$0]++;打印 $0"_"a[$0]}'
(从这里窃取的代码:)
但是我找不到一种方法来保存文件中的更改(例如像带 -i 的 sed)并且我不能将它重定向到一个新文件,因为它只是 prints/saves headers.
有什么想法吗?
谢谢
P
看来问题是你不理解你在别处找到的代码:
awk ' ~ /^>/ {gsub(" ", "", [=10=]); a[[=10=]]++; print [=10=]"_"a[[=10=]]}'
从外观上看,它会执行您想要的替换并打印以 >
.
开头的行
所以缺少的部分是打印剩余的行而不做任何修改。
你可以这样做:
awk ' ~ /^>/ { gsub(" ", "", [=11=]); a[[=11=]]++; [=11=] = [=11=]"_"a[[=11=]] } { print }'
也就是说,将 print
更改为第一个块中的赋值,并添加一个无条件的第二个块,该块始终打印所有内容。
代码可以进一步简化,通过将增量与赋值结合并将{ print }
更改为常见的shorthand(只是一个1
条件和默认操作,打印) .
如评论中所述,可以通过传递正则表达式文字作为第一个参数来改进对 gsub
的调用,而不是必须在使用前转换为正则表达式的字符串。也可以通过删除默认的最后一个参数 [=20=]
来缩短它。
awk ' ~ /^>/ { gsub(/ /, ""); [=12=] = [=12=] "_" ++a[[=12=]] } 1'
要覆盖原始文件,只需重定向到一个临时文件然后覆盖原始文件:
awk '...' input > tmp && mv tmp input
或使用 GNU awk,如评论中所述:
awk -i inplace '...' input
我一直在努力使用 awk 找出一种方法来找到相同的模式,并在它们的末尾添加一个标签,以显示它们在文件中出现的次数。 例如,如果Spiroplasma_culicicola出现了7次,那么在第一次出现的旁边写Spiroplasma_culicicola_1,在第二次出现的旁边写Spiroplasma_culicicola_2在第三次出现的旁边写Spiroplasma_culicicola_3 等等等等
但是我有一个如下所示的 fasta 文件:
>Spiroplasma_taiwanense
GKGVKYKNEKIIRKEGKAAGKMTTDVIADMLTRIRNANQRFHKEVVIPGSKVKLEIANIL
KKEGFIEDFKVADDFKKDITISLKYRGKTRVIKGLKRISKPGLRVYSHATEIPQVLNGLG
IAIVSTSHGIMTDKEARQQNAGGEVLAFVW
>Spiroplasma_diminutum
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
KSKILRGDVVKVIAGSHKGKIGPVVKLSKDKKRVYVEGIVAIK-HAKPSQTDQEGGIREI
PAGVDISNVSLVDPKVKDSATRVGYKIADGKKVRIAKKSGSEVK-MIQNESRLKVADNSG
>Spiroplasma_diminutum
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
...
所以我想添加 "tag",该数字仅显示在 headers 旁边!因此上面的文件应该是这样的:
>Spiroplasma_taiwanense_1
GKGVKYKNEKIIRKEGKAAGKMTTDVIADMLTRIRNANQRFHKEVVIPGSKVKLEIANIL
KKEGFIEDFKVADDFKKDITISLKYRGKTRVIKGLKRISKPGLRVYSHATEIPQVLNGLG
IAIVSTSHGIMTDKEARQQNAGGEVLAFVW
>Spiroplasma_diminutum_1
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
KSKILRGDVVKVIAGSHKGKIGPVVKLSKDKKRVYVEGIVAIK-HAKPSQTDQEGGIREI
PAGVDISNVSLVDPKVKDSATRVGYKIADGKKVRIAKKSGSEVK-MIQNESRLKVADNSG
>Spiroplasma_diminutum_2
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
...
根据之前回答的问题,我认为我应该使用 awk,像这样: awk '$1 ~ /^>/ {gsub(" ", "", $0);一个[$0]++;打印 $0"_"a[$0]}'
(从这里窃取的代码:
但是我找不到一种方法来保存文件中的更改(例如像带 -i 的 sed)并且我不能将它重定向到一个新文件,因为它只是 prints/saves headers.
有什么想法吗?
谢谢 P
看来问题是你不理解你在别处找到的代码:
awk ' ~ /^>/ {gsub(" ", "", [=10=]); a[[=10=]]++; print [=10=]"_"a[[=10=]]}'
从外观上看,它会执行您想要的替换并打印以 >
.
所以缺少的部分是打印剩余的行而不做任何修改。
你可以这样做:
awk ' ~ /^>/ { gsub(" ", "", [=11=]); a[[=11=]]++; [=11=] = [=11=]"_"a[[=11=]] } { print }'
也就是说,将 print
更改为第一个块中的赋值,并添加一个无条件的第二个块,该块始终打印所有内容。
代码可以进一步简化,通过将增量与赋值结合并将{ print }
更改为常见的shorthand(只是一个1
条件和默认操作,打印) .
如评论中所述,可以通过传递正则表达式文字作为第一个参数来改进对 gsub
的调用,而不是必须在使用前转换为正则表达式的字符串。也可以通过删除默认的最后一个参数 [=20=]
来缩短它。
awk ' ~ /^>/ { gsub(/ /, ""); [=12=] = [=12=] "_" ++a[[=12=]] } 1'
要覆盖原始文件,只需重定向到一个临时文件然后覆盖原始文件:
awk '...' input > tmp && mv tmp input
或使用 GNU awk,如评论中所述:
awk -i inplace '...' input