使用awk循环将文件名添加到fasta headers?

add filename to fasta headers in a loop with awk?

我知道之前有人问过这个问题,但我找不到有效的解决方案 - 出于某种原因,当我尝试 Whosebug 中发布的任何其他解决方案时,它们根本不起作用

我有一个包含 900 多个 fasta 文件的目录,它们都以“.faa”结尾 其中一些名字是:

TLLD001.faa TLLD002.faa TLLD003.faa TLLD004.faa TLLD005.faa

等等等等

在每个文件中,header 的 fasta 是:

   >scaffold4567
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >scaffold0034
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

   >NODE_212
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >NODE_86667
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

等等等等

我想浏览所有文件并通过添加文件名替换 header 例如,TLLD001.faa

   >scaffold4567
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >scaffold0034
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
   >scaffold7667
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >scaffold6778
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

应该变成

   >TLLD001_scaffold4567
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >TLLD001_scaffold0034
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
   >TLLD001_scaffold7667
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >TLLD001_scaffold6778
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

这很好用,但我每次都必须指定一个文件 $awk '/>/{sub(">","&"FILENAME"_");sub(/\.faa/,x)}1' TLLD001.faa

所以不是我的菜

这似乎适用于我作为测试所做的 3-4 个文件,但它不适用于我的 900 多个文件目录 - 永远 -

for i in *.faa; do 
    sed -i "s/^>/>${i}_/g" *.faa
done

以下根本不起作用:

$for file in *.fasta; do awk '/^>/ {printf("\n%s\n",[=16=]);next; } { printf("%s",[=16=]);}  END {printf("\n");}' < $file > "`basename $file .fasta`_single-line.fasta"; done

$for file in *.faa; do awk '/>/{sub(">","&"${file}"_");sub(/\.faa/,x)}1' < $file > "`basename $file .faa`_mod.faa"; done

我也不知道为什么!任何有关如何使用这个全能但神秘的“awk”的帮助和解释将不胜感激

谢谢 P

应该这样做

$ for f in *.faa; do sed -i "s/^>/>${f}_/" "$f"; done

但是也会插入文件扩展名。要删除扩展名,请更改为 ${f%.*}

试试 Perl one-liner。

perl -i -0777 -pe ' $x=$ARGV;$x=~s/\.faa//g; s/\>/>${x}_/ ' *faa

这是break-up

$ cat  TLLD001.faa
>scaffold4567
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold0034
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>scaffold7667
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold6778
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

$ cat TLLD002.faa
>NODE_212
WRVLSTSFNGIKYEQSAAFAMIPSTT
>NODE_86667
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

在没有 in-replace

的情况下执行命令
$ perl -0777 -pe ' $x=$ARGV;$x=~s/\.faa//g; s/\>/>${x}_/ ' *faa
>TLLD001_scaffold4567
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold0034
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>scaffold7667
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold6778
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>TLLD002_NODE_212
WRVLSTSFNGIKYEQSAAFAMIPSTT
>NODE_86667
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

与in-replace

$ perl -i -0777 -pe ' $x=$ARGV;$x=~s/\.faa//g; s/\>/>${x}_/ ' *faa

文件已修改

$ cat TLLD001.faa
>TLLD001_scaffold4567
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold0034
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>scaffold7667
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold6778
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
$ cat TLLD002.faa
>TLLD002_NODE_212
WRVLSTSFNGIKYEQSAAFAMIPSTT
>NODE_86667
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
$

sed 解决方案是可行的方法,但您在命令中重复了 glob!

而不是

for f in *.faa; do sed -i "s/^>/>${f%.faa}/g" *.faa; done

在sed命令中使用${f}变量,否则再次为sed命令展开!

for f in *.faa; do sed -i "s/^>/>${f%.faa}/g" "${f}"; done

我还使用了一些 bash 变量替换来简单地从文件中删除 .faa。

我知道它很旧,但在 sed 的 OSX 版本中,-i 选项需要扩展。因此,您需要添加一个 -e 参数并将 '' 作为参数提供给 -i.

for f in *.faa; do sed -i '' -e "s/^>/>${f%.faa}_/g" "${f}"; done

对于那里的 OSX 人 :)