将fasta标题中的单个字符替换为awk或sed



我正在bash中使用一个fasta文件,其头以">"并以"C"或者"+"。像这样:

>chr1:35031657-35037706+
GGTGGACTAGCCAGTGAATGTCAACGCGTCCCTA
CCTAAGGCGATATCCGCAGCCGCCCGCGTCCCTA
>chr1:71979382-71985425C
agattaaatgaactattacacataaagtgcttac
ttacacataaagtgcttacgaactattacaggga

我想使用awk (gsub?)或sed将标题的最后一个字符更改为"+"如果是"c"。基本上,我希望所有的序列都以"+"结尾。没有C。

所需输出:

>chr1:35031657-35037706+
GGTGGACTAGCCAGTGAATGTCAACGCGTCCCTA
CCTAAGGCGATATCCGCAGCCGCCCGCGTCCCTA
>chr1:71979382-71985425+
agattaaatgaactattacacataaagtgcttac
ttacacataaagtgcttacgaactattacaggga

不需要改变序列。我认为这是相当直接的,但我正在努力使用其他帖子来做这件事。我知道awk '/^>/ && /C$/{print $0}'将打印以">"开头的标题并以"C"结尾,但我不知道如何用"+"s代替所有的"C"s。

谢谢你的帮助!

我认为这将更容易做到在sed:

sed '/^>/ s/C$/+/'

翻译:以">"开头的行,替换"C"在行末加上"+"。注意,如果"C"不匹配,没有错误,它只是不替换任何东西。而且,与awk不同的是,sed在处理后会自动打印每一行。

如果你真的想使用awk,等效的是:

awk '/^>/ {sub("C$","+",$0)}; {print}'

使用下面的Perl一行代码:

perl -pe 's{^(>.*)C$}{$1+}' input.fasta > output.fasta

或者,就地修改文件:

perl -i.bak -pe 's{^(>.*)C$}{$1+}' input.fasta

Perl单行程序使用这些命令行标志:
-e:告诉Perl查找内联代码,而不是在文件中查找。
-p:每次循环输入一行,默认赋值给$_。在每次循环迭代后添加print $_
-i.bak:就地编辑输入文件(覆盖输入文件)。在覆盖之前,通过在原始文件的名称后面附加扩展名.bak来保存原始文件的备份副本。如果您想跳过写入备份文件,只需使用-i并跳过扩展名。

s{^(>.*)C$}{$1+}:将以>(= fasta header)开始并以C结束的行更改为与C更改为+相同的行,
^标记该行的开始,$标记该行的结束。.*表示重复0次及以上的字符。(>.*)捕获内部的模式,即整行减去C,并将其存储在捕获变量$1中。

参见:
perldoc perlrun:如何执行Perl解释器:命令行开关
perldoc perlre: Perl正则表达式(regexes)
perldoc perlre: Perl正则表达式(regexes):量词;字符类和其他特殊转义;断言;捕获组
perldoc perlrequick: Perl正则表达式快速入门

您可以使用GNUAWK来完成此任务,让file.txt内容为

>chr1:35031657-35037706+
GGTGGACTAGCCAGTGAATGTCAACGCGTCCCTA
CCTAAGGCGATATCCGCAGCCGCCCGCGTCCCTA
>chr1:71979382-71985425C
agattaaatgaactattacacataaagtgcttac
ttacacataaagtgcttacgaactattacaggga

然后

awk 'BEGIN{FPAT=".";OFS=""}$1==">"{$NF="+"}{print}' file.txt

给输出

>chr1:35031657-35037706+
GGTGGACTAGCCAGTGAATGTCAACGCGTCCCTA
CCTAAGGCGATATCCGCAGCCGCCCGCGTCCCTA
>chr1:71979382-71985425+
agattaaatgaactattacacataaagtgcttac
ttacacataaagtgcttacgaactattacaggga

解释:我通知GNUAWK使用FPAT的字段是任何单个字符,使用OFS的输出字段分隔符是空字符串。对于第一个字段,即第一个字符是>的每一行,我将最后一个字段($NF)的值更改为+。请注意,这也适用于以+结尾的头,但这不是问题,因为它将+更改为+。无论修改与否,每一行都是print编辑的。

(在GNU Awk 5.0.1中测试)

最新更新