如何用一个文件的名称重命名多个 multi-fasta 文件中的 headers?

How to rename headers in many multi-fasta files with the name of a file?

我有一个包含数百个 multi-FASTA 文件的目录。这些文件以种或属的名称命名,例如:

Bubo_bubo.fasta
Poa_CC7849.fasta
Homo_sapiens.fasta
...

在每个文件中,header 由 Trinity assembler 自动生成,看起来类似于此示例:

>c5_g1_i1 len=168 path=[174:0-148 24:148-168]

我想重命名每个文件中的 header,添加有关其来源物种的信息。所以换句话说,header 应该在文件名的开头。例如,如果上面的 header 来自 Bubo_bubo.fasta 它应该看起来像:

>Bubu_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]

所以我想写一个循环,它将获取一个文件名,并使用它在这个特定文件的每个 fasta header 中添加此信息,我想对目录中的所有文件都这样做.

以下应该可以解决问题:

awk '(FNR==1){f=FILENAME;sub(/\.[A-Za-z]*$/,"_",f)}
     /^>/{[=10=]=">" f substr([=10=],2)}
     1' Bubo_bubo.fasta

但是,这会将所有内容写入屏幕,您可能对拥有新文件感兴趣。因此,您可以将 bash 与多个文件的重定向一起使用,如:

for f in *.fasta; do
   awk '(FNR==1){f=FILENAME;sub(/\.[A-Za-z]*$/,"_",f)}
        /^>/{[=11=]=">" f substr([=11=],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
     }
     /^>/{[=12=]=">" f substr([=12=],2)}           # if header found, update it
     {print > fout}                        # print to output file
    ' *.fasta