我有多个 fasta 文件,其名称以P
(例如PANS_1_2
, PANS_1_5
, PANS_200_2
, PANS_200_2
)开头。
这些文件有这样的标题
>1_1262659_105.258519
>2_809301_107.252177
>3_422941_112.146787
>4_413692_100.238323
我正在尝试将这些文件的标头替换为filename_ctg1
.如果输入 fasta 文件是PANS_1_2
,则输出文件 (PANS_1_2.fasta) 中的标头应为:
>PANS_1_2_ctg1
>PANS_1_2_ctg2
>PANS_1_2_ctg3
我尝试了以下代码:
for sample in P*;do echo -en $sample;awk '/>.*/{sub(/[^>]*/,">$sample_ctg"++i)}1' $sample;done > $sample.fasta
提到的脚本不会产生所需的输出。
答案1
和awk
:
awk 'FNR==1{ close(out); inc=0; fileName=substr(FILENAME,3); out=fileName".fasta" }
/^>/{ $0= ">"fileName"_ctg"(++inc) }
{ print > out }' ./P*
FILENAME
是一个awk保存当前处理输入文件名的变量;我们将其设置为首先从中fileName
乘坐;./
文件名中的前缀点斜杠./
用于避免像读取此类文件那样命名的文件PANS=1_2
出现awk
问题字符串作为一个多变的当这些出现在awk
代码之后时;
双引号“...”内的所有内容实际上都是字符串;
++inc
是预增量算术表达式,用于对每个标头进行编号,并将重置回0对于FNR==1
我们使用的下一个输入文件。
它$0
代表 中的整行/记录awk
,因此我们更新 ( $0= ...
) 那些以字符开头的行>
,然后使用“>”字符文件名后面跟着_ctg
字符串和增量数字。
第三行我们print
当前行值是一个文件名,其名称与当前相同文件名阅读者awk并将“.fasta”字符串也附加到其中。
答案2
在 for 循环中使用 GNU sed。
tmp=$(mktemp)
for sample in ./P*; do
knt=$(grep -c '^>' < "$sample") || continue
seq -f ">${sample}_ctg%g" "$knt" > "$tmp"
sed -e "/^>/R $tmp" -e '//d' < "$sample" > "$sample.fasta"
done
- 获取给定示例文件中的标头数量。
- 根据上一步中的示例文件名和标头计数构造要添加的标头。
- 将每个标题行替换为从上一步构建的标题文件中读取的下一行。