我有一个包含数百个多FASTA文件的目录。这些文件以物种或属的名称来调用,例如:
Bubo_bubo.fasta
Poa_CC7849.fasta
Homo_sapiens.fasta
...
在每个filem内,头文件都是由Trinity assembler自动生成的,看起来类似于以下示例:
>c5_g1_i1 len=168 path=[174:0-148 24:148-168]
我想重命名每个文件的标题,以添加有关其来源物种的信息。因此,换句话说,标头应在文件的开头包含文件名。例如,如果上面的标头来自Bubo_bubo.fasta
,则其外观应为:
>Bubu_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
所以我想编写一个循环,该循环将使用一个文件名,并使用它在此特定文件的每个fasta标头中添加此信息,并且我想对目录中的所有文件执行此操作。
答案 0 :(得分:2)
以下应为您解决问题:
awk '(FNR==1){f=FILENAME;sub(/\.[A-Za-z]*$/,"_",f)}
/^>/{$0=">" f substr($0,2)}
1' Bubo_bubo.fasta
但是,这会将所有内容写入屏幕,您可能会想拥有新文件。因此,您可以将bash与多个文件一起使用重定向,例如:
for f in *.fasta; do
awk '(FNR==1){f=FILENAME;sub(/\.[A-Za-z]*$/,"_",f)}
/^>/{$0=">" f substr($0,2)}
1' "$f" > "/path/to/new/location/$(basename $f)"
done
如果您真的想要,您可以在awk本身中做所有事情,这就是:
awk '(FNR==1){ # When a new file is opened (first record)
close(fout); # close previous output file
fout=FILENAME
sub(".*/", "", fout) # get basename of file
f=fout # set f to basename of file
fout="path/to/new/location/" fout # prepend output directory
sub(/\.[A-Za-z]*$/,"_",f) # remove extention from f
}
/^>/{$0=">" f substr($0,2)} # if header found, update it
{print > fout} # print to output file
' *.fasta