【问题标题】:Use AWK to search through fasta file, given a second file containing sequence names给定包含序列名称的第二个文件,使用 AWK 搜索 fasta 文件
【发布时间】:2016-11-24 06:54:47
【问题描述】:

我有 2 个文件。一个是包含多个 fasta 序列的 fasta 文件,而另一个文件包含我要搜索的候选序列的名称(文件示例如下)。

seq.fasta

>Clone_18
GTTACGGGGGACACATTTTCCCTTCCAATGCTGCTTTCAGTGATAAATTGAGCATGATGGATGCTGATAATATCATTCCCGTGT
>Clone_23
GTTACGGGGGGCCGAAAAACACCCAATCTCTCTCTCGCTGAAACCCTACCTGTAATTTGCCTCCGATAGCCTTCCCCGGTGA
>Clone_27-1
GTTACGGGGACCACACCCTCACACATACAAACACAAACACTTCAAGTGACTTAGTGTGTTTCAGCAAAACATGGCTTC
>Clone_27-2
GTTACGGGGACCACACCCTCACACATACAAACACAAACACTTCAAGTGACTTAGTGTGTTTCAGCAAAACATGGCTTCGTTTTGTTCTAGATTAACTATCAGTTTGGTTCTGTTTGTCCTCGTACTGGGTTGTGTCAATGCACAACTT
>Clone_34-1
GTTACGGGGGAATAACAAAACTCACCAACTAACAACTAACTACTACTTCACTTTTCAACTACTTTACTACAATACTAAGAATGAAAACCATTCTCCTCATTATCTTTGCTCTCGCTCTTTTCACAAGAGCTCAAGTCCCTGGCTACCAAGCCATCG
>Clone_34-3
GTTACGGGGGAATAACAAAACTCACCAACTAACAACTAACTACTACTTCACTTTTCAACTACTTTACTACAATACTAAGAATGAAAACCATTCTCCTCATTATCTTTGCTCTCGCTCTTTTCACAAGAGCTCAAGTCCCTGGCTACCAAGCCATCGATATCGCTGAAGCCCAATC
>Clone_44-1
GTTACGGGGGAATCCGAATTCACAGATTCAATTACACCCTAAAATCTATCTTCTCTACTTTCCCTCTCTCCATTCTCTCTCACACACTGTCACACACATCC
>Clone_44-3
GTTACGGGGGAATCCGAATTCACAGATTCAATTACACCCTAAAATCTATCTTCTCTACTTTCCCTCTCTCCATTCTCTCTCACACACTGTCACACACATCCCGGCAGCGCAGCCGTCGTCTCTACCCTTCACCAGGAATAAGTTTATTTTTCTACTTAC

名称.txt

Clone_23
Clone_27-1

我想使用 AWK 搜索 fasta 文件,并获取名称保存在另一个文件中的给定候选人的所有 fasta 序列。

awk 'NR==FNR{a[$1]=$1} BEGIN{RS="\n>"; FS="\n"} NR>FNR {if (match($1,">")) {sub(">","",$1)} for (p in a) {if ($1==p) print ">"$0}}' name.txt seq.fasta

问题是我只能提取name.txt中第一个候选的序列,像这样

>Clone_23
GTTACGGGGGGCCGAAAAACACCCAATCTCTCTCTCGCTGAAACCCTACCTGTAATTTGCCTCCGATAGCCTTCCCCGGTGA

任何人都可以帮助修复上面的单行 awk 命令吗?

【问题讨论】:

  • 您在发布答案后彻底改变了问题。我已经回滚了。请在这种情况下发布一个新问题。 (并展示您尝试从此处获得的答案中调整的内容)
  • 我只能在 90 分钟内发布 1 个问题。我可以在回答会话中发布新示例吗?
  • 嗯,其实还是推荐使用cmets或者re-edit question(因为我需要用format来展示例子)
  • 不会被版主删除。使用 90 分钟自己思考解决方案怎么样?我想他们就是为此而生的。实际上只有 30 分钟,因为你在一小时前问过这个问题。
  • 我建议您利用这段时间提出一个真正具有代表性的示例,这样我们就不会浪费更多时间来帮助您解决您没有遇到的问题。

标签: awk fasta


【解决方案1】:

如果可以,甚至还想打印名字,你可以简单地使用grep

grep -Ff name.txt -A1 a.fasta
  • -f name.txtname.txt 中挑选模式
  • -F 将它们视为文字字符串而不是正则表达式
  • A1 打印匹配行和后续行

如果输出中不需要这些名称,我会简单地通过管道传输到另一个 grep

above_command | grep -v '>'

awk 解决方案可能如下所示:

awk 'NR==FNR{n[$0];next} substr($0,2) in n && getline' name.txt a.fasta

在多行版本中更好地解释:

# True as long as we are reading the first file, name.txt
NR==FNR {
    # Store the names in the array 'n'
    n[$0]
    next
}

# I use substr() to remove the leading `>` and check if the remaining
# string which is the name is a key of `n`. getline retrieves the next line
# If it succeeds the condition becomes true and awk will print that line
substr($0,2) in n && getline

【讨论】:

  • 嗯,我想知道如果/当 getline 失败时会做什么...... ;-)。如果你必须使用 getline(提示 - 你不在这里),那么至少要保护自己免受 if ( (getline line) > 0 ) print line 的失败。见awk.freeshell.org/AllAboutGetline
  • @EdMorton 更新了它。谢谢你的帮助!我喜欢将getline > 0 放入条件中。 awk 摇滚! :)
  • 听起来不错。我对 getline 的主要反感是,当我看到/编写使用它的脚本时,我必须在心里仔细检查所有副作用清单,看看它们中的任何一个是否会在当前应用程序中产生负面后果。通常我最终会决定“它可能会好起来”,大约 50% 的时间我是对的 :-) 但主要是我宁愿不必考虑它,所以发现不使用它更容易除了在几个应用程序中它显然是正确的解决方案(例如递归下降解析器)。
  • 好点。如果程序员需要考虑太多事情,他可能会忘记一些事情。具有尽可能少的副作用的解决方案通常是更好的方法。特别是如果没有编写初始代码的人必须稍后修改它。到目前为止,对getline 没有强烈的看法。我很少使用它。但我明白你的观点。
  • 没错。在调用getline 之后,您需要复制已经在主体中的> 测试。这是邪恶的,这就是我要说的;-)。
【解决方案2】:
$ awk 'NR==FNR{n[">"$0];next} f{print f ORS $0;f=""} $0 in n{f=$0}' name.txt seq.fasta
>Clone_23
GTTACGGGGGGCCGAAAAACACCCAATCTCTCTCTCGCTGAAACCCTACCTGTAATTTGCCTCCGATAGCCTTCCCCGGTGA
>Clone_27-1
GTTACGGGGACCACACCCTCACACATACAAACACAAACACTTCAAGTGACTTAGTGTGTTTCAGCAAAACATGGCTTC

【讨论】:

  • 如果一个序列被分成多行,上面的命令只能读取第一行。这就是我更改默认 RS 的原因。请参阅上面的更改示例
  • 我在您的示例中看不到任何更改。调整此解决方案以适用于多行记录是微不足道的,但我不倾向于这样做,因为我无法想象为什么您不会在您的问题和您的示例中首先包含该信息不过,我希望很明显,要解析文件,我们需要知道文件内容的格式!您是否还有其他惊喜可供使用,例如多个连续的> 行或.... 发布具有准确输入/输出的新问题,我们将从那里开始。
猜你喜欢
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
相关资源
最近更新 更多