使用 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
我有一个应该是简单的问题,但我缺乏 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