【问题标题】:add filename to fasta headers in a loop with awk?使用 awk 在循环中将文件名添加到 fasta 标头?
【发布时间】:2021-02-09 23:03:50
【问题描述】:

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

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

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

等等等等

在每个文件中,fasta 的标题是:

   >scaffold4567
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >scaffold0034
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

   >NODE_212
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >NODE_86667
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

等等等等

我想浏览所有文件并通过添加文件名来替换标题 例如,TL​​LD001.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",$0);next; } { printf("%s",$0);}  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

【问题讨论】:

  • 能否请您在代码标签中覆盖您的示例/代码,看起来您使用了引号标签,这使示例更难理解。

标签: bash loops awk header fasta


【解决方案1】:

应该这样做

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

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

【讨论】:

    【解决方案2】:

    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。

    【讨论】:

    • 你还是需要引用"${f}",或者干脆"$f"
    【解决方案3】:

    试试 Perl 单行代码。

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

    这是分手

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

    在没有替换的情况下执行命令

    $ 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
    

    替换

    $ 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
    $
    

    【讨论】:

      【解决方案4】:

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

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

      对于 OSX 人来说 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-11
        • 1970-01-01
        • 2014-04-04
        • 2017-07-09
        相关资源
        最近更新 更多