使用 awk 在 fasta headers 中的定界符后保留文本

retaining text after delimiter in fasta headers using awk

我有一个应该是简单的问题,但我缺乏 awk 知识阻碍了我。

我想清理以下格式的 fasta 文件的 headers:

>HWGG454_Clocus2_Locus3443_allele1
ATTCTACTACTACTCT
>GHW757_clocus37_Locus555662_allele2
CTTCCCTACGATG
>TY45_clocus23_Locus800_allele0
TTCTACTTCATCT

我想清理每个 header(以“>”开头的行)以仅保留信息部分,即带有或不带有等位基因部分的第二个“_Locus*”。

我认为 awk 是执行此操作的简单方法,但我无法让它正常工作。

如果我只想保留 header 的第一列文本到“_”分隔符,以及下面的序列,我 运行 这个(假设这个玩具示例在文件 test.fasta):

 cat test.fasta | awk -F '_' '{print }'

>HWGG454
ATTCTACTACTACTCT
>GHW757
CTTCCCTACGATG
>TY45
TTCTACTTCATCT

但是,我想要的是只保留 "Locus*" 文本,它位于第三个定界符之后,但是,使用这段代码我得到了这个:

cat test.fasta | awk -F '_' '{print }'
Locus3443

Locus555662

Locus800

我在这里做错了什么?

谢谢。

我理解这意味着您想从 header 行中选择 Locus 字段并保持其他不变。那么:

awk -F _ '/^>/ { print ; next } 1' filename

也许是最简单的方法。其工作方式如下:

/^>/ {      # in lines that begin with >
  print   # print the third field
  next      # and go to the next line.
}
1           # print other lines unchanged. Here 1 means true, and the
            # default action (unchanged printing) is performed.

这里要理解的是 awk 的控制流:awk 代码由条件和相关动作组成,如果条件为真,则执行动作。

/^>/ 是整个记录的正则表达式匹配(默认为行);如果该行以 > 开头(因为 ^ 匹配开头),则为真,所以

/^>/ { print ; next }

将使 awk 在以 > 开头的行中执行 print ; next。不太直接的部分是

1

打印行不变。我们只有在第一个动作没有被执行时才会到达这里(因为其中的 next),并且这个 1 被读取为一个始终为真的条件——非零值在 awk 中为真.

现在,如果省略 awk 语句中的条件或操作,则使用默认值。默认操作是打印未更改的行,这利用了它。同样可以写成

1 { print }

{ print }

在后一种情况下,省略条件并使用默认条件"true"。 1 是这个的最短变体,因此是惯用语。

您需要对下面的行进行第二个 awk 匹配。例如

cat test.fasta | awk -F _ '/^>/ { print "_" } /^[A-Z]/ {print }'

输出:

Locus3443_allele1
ATTCTACTACTACTCT
Locus555662_allele2
CTTCCCTACGATG
Locus800_allele0
TTCTACTTCATCT

如果您不想 _allele1 位从 awk 脚本中删除 "_"

$ awk -F_ '{print (/^>/ ?  : [=10=])}' file
Locus3443
ATTCTACTACTACTCT
Locus555662
CTTCCCTACGATG
Locus800
TTCTACTTCATCT

你可以在每一行做一个正则表达式:

$ awk '{ sub(/^.*_L/,"L"); print [=10=]}' /tmp/fasta.txt
Locus3443_allele1
ATTCTACTACTACTCT
Locus555662_allele2
CTTCCCTACGATG
Locus800_allele0
TTCTACTTCATCT