借助 TSV 文件中的两列进行过滤
Filtering with help of two columns from a TSV file
我有以下文件:
Pepper1.55ch01 PGA1.55 gene 63209 63880 . - . ID=CA01g00010;Name=CA01g00010
Pepper1.55ch01 PGA1.55 mRNA 63209 63880 . - . ID=mRNA.CA01g00010;Parent=CA01g00010;Note="Detected protein of unknown function"
Pepper1.55ch01 PGA1.55 exon 63209 63300 . - . ID=exon:CA01g00010:1;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63209 63300 . - 0 ID=CDS:CA01g00010:1;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 exon 63445 63730 . - . ID=exon:CA01g00010:2;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63445 63730 . - 0 ID=CDS:CA01g00010:2;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 exon 63758 63880 . - . ID=exon:CA01g00010:3;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63758 63880 . - 0 ID=CDS:CA01g00010:3;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 gene 112298 112938 . - . ID=CA01g00020;Name=CA01g00020
Pepper1.55ch01 PGA1.55 mRNA 112298 112938 . - . ID=mRNA.CA01g00020;Parent=CA01g00020;Note="PREDICTED: protein ECERIFERUM 3-like [Solanum tuberosum]"
Pepper1.55ch01 PGA1.55 exon 112298 112457 . - . ID=exon:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 CDS 112298 112457 . - 0 ID=CDS:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 exon 112565 112743 . - . ID=exon:CA01g00020:2;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 CDS 112565 112743 . - 0 ID=CDS:CA01g00020:2;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 exon 112828 112938 . - . ID=exon:CA01g00020:3;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 CDS 112828 112938 . - 0 ID=CDS:CA01g00020:3;Parent=mRNA.CA01g00020
...
现在,如果第 3 列是基因,我想从第 9 列中提取 ID(例如 CA01g00010)。但是,以下 awk/grep 命令传送了不同数量的 ID。
> awk '{print ,}' Pepper_1.55.gene_models-1-12.gff3 | grep gene | wc -l
30265
> awk '{print }' Pepper_1.55.gene_models-1-12.gff3 | grep gene | wc -l
30242
似乎第 9 列有时包含该基因。我错过了什么?
I want to extract ID (e.g. CA01g00010
) from column 9
if column 3
is a gene
您可以使用这个 awk
解决方案:
awk -F '\t' ' == "gene" {gsub(/^ID=|;.*/, "", ); print }' file.tsv
CA01g00010
CA01g00020
详情:
-F '\t'
:此 awk
命令使用 \t
(制表符)作为输入字段分隔符。
== "gene"
:当</code>为<code>gene
时,采取行动
{...}
是包含以下内容的操作块:
gsub(/^ID=|;.*/, "", )
:从 </code></li> 中删除初始 <code>ID=
部分和 ;
之后的任何内容
print
: 打印
使用您展示的示例,请尝试以下 awk
代码。
awk -F'\t' == "gene" && ~ /^ID=/ && split(,array,"[=;]"){print array[2]}' Input_file
解释: 简单的解释就是,Input_file的所有行都将字段分隔符设为制表符。然后在主程序中,检查条件是否第 3 列是基因并且第 9 列从 ID= 开始并将第 9 列拆分为名为数组的数组,分隔符为 =;
并打印第 9 列的第 2 个元素。
假设:
- 不必担心不区分大小写的匹配(例如,不必匹配
GENE
或 Gene
)
- 第9列中的匹配可以进一步规定为以
ID=CA01g00010;
开头的列
- OP 的当前 objective 似乎是匹配行计数的集合;否则 OP 应该更新问题以说明所需的输出(例如,打印整行?打印列的子集?)
修改 OP 的示例输入以提供匹配和不匹配的混合:
$ cat input.dat
Pepper1.55ch01 PGA1.55 gene 63209 63880 . - . ID=CA01g00010;Name=CA01g00010
Pepper1.55ch01 PGA1.55 exon 63209 63880 . - . ID=CA01g00010; skipme; Name=CA01g00010
Pepper1.55ch01 PGA1.55 gene 63209 63300 . - . skipme; ID=CA01g00010:1;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63758 63880 . - 0 ID=CDS:CA01g00010:3;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 gene 112298 112938 . - . ID=CA01g00020;Name=CA01g00020
Pepper1.55ch01 PGA1.55 exon 112298 112457 . - . ID=exon:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 gene 112298 112938 . - . ID=DE03g00230; skipme; Name=CA01g00020
Pepper1.55ch01 PGA1.55 exon 112298 112457 . - . ID=exon:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 gene 63209 63880 . - . ID=CA01g00010;Name=CA01g00010
Pepper1.55ch01 PGA1.55 exon 63209 63880 . - . ID=CA01g00010; skipme; Name=CA01g00010
一个 awk
替代 OP 当前 awk|grep|wc
代码的想法:
awk -F'\t' -v col3="${col3}" -v id="${id}" ' # allow OP to define search strings for column 3 and the "ID=" match in column 9
== col3 && match(,"ID="id";")==1 { cnt++ } # if we find both matches then increment our counter
END { print cnt+0 } # "+0" to force default value from empty string to 0
' input.dat
对于 bash
变量 col3='gene'
和 id=CA01g00010
我们得到:
2
对于 bash
变量 col3='gene'
和 id='DE03g00230'
我们得到:
1
对于 bash
变量 col3='gene'
和 id='findme'
我们得到:
0
我有以下文件:
Pepper1.55ch01 PGA1.55 gene 63209 63880 . - . ID=CA01g00010;Name=CA01g00010
Pepper1.55ch01 PGA1.55 mRNA 63209 63880 . - . ID=mRNA.CA01g00010;Parent=CA01g00010;Note="Detected protein of unknown function"
Pepper1.55ch01 PGA1.55 exon 63209 63300 . - . ID=exon:CA01g00010:1;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63209 63300 . - 0 ID=CDS:CA01g00010:1;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 exon 63445 63730 . - . ID=exon:CA01g00010:2;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63445 63730 . - 0 ID=CDS:CA01g00010:2;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 exon 63758 63880 . - . ID=exon:CA01g00010:3;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63758 63880 . - 0 ID=CDS:CA01g00010:3;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 gene 112298 112938 . - . ID=CA01g00020;Name=CA01g00020
Pepper1.55ch01 PGA1.55 mRNA 112298 112938 . - . ID=mRNA.CA01g00020;Parent=CA01g00020;Note="PREDICTED: protein ECERIFERUM 3-like [Solanum tuberosum]"
Pepper1.55ch01 PGA1.55 exon 112298 112457 . - . ID=exon:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 CDS 112298 112457 . - 0 ID=CDS:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 exon 112565 112743 . - . ID=exon:CA01g00020:2;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 CDS 112565 112743 . - 0 ID=CDS:CA01g00020:2;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 exon 112828 112938 . - . ID=exon:CA01g00020:3;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 CDS 112828 112938 . - 0 ID=CDS:CA01g00020:3;Parent=mRNA.CA01g00020
...
现在,如果第 3 列是基因,我想从第 9 列中提取 ID(例如 CA01g00010)。但是,以下 awk/grep 命令传送了不同数量的 ID。
> awk '{print ,}' Pepper_1.55.gene_models-1-12.gff3 | grep gene | wc -l
30265
> awk '{print }' Pepper_1.55.gene_models-1-12.gff3 | grep gene | wc -l
30242
似乎第 9 列有时包含该基因。我错过了什么?
I want to extract ID (e.g.
CA01g00010
) from column9
if column3
is agene
您可以使用这个 awk
解决方案:
awk -F '\t' ' == "gene" {gsub(/^ID=|;.*/, "", ); print }' file.tsv
CA01g00010
CA01g00020
详情:
-F '\t'
:此awk
命令使用\t
(制表符)作为输入字段分隔符。== "gene"
:当</code>为<code>gene
时,采取行动{...}
是包含以下内容的操作块:gsub(/^ID=|;.*/, "", )
:从</code></li> 中删除初始 <code>ID=
部分和;
之后的任何内容print
: 打印
使用您展示的示例,请尝试以下 awk
代码。
awk -F'\t' == "gene" && ~ /^ID=/ && split(,array,"[=;]"){print array[2]}' Input_file
解释: 简单的解释就是,Input_file的所有行都将字段分隔符设为制表符。然后在主程序中,检查条件是否第 3 列是基因并且第 9 列从 ID= 开始并将第 9 列拆分为名为数组的数组,分隔符为 =;
并打印第 9 列的第 2 个元素。
假设:
- 不必担心不区分大小写的匹配(例如,不必匹配
GENE
或Gene
) - 第9列中的匹配可以进一步规定为以
ID=CA01g00010;
开头的列
- OP 的当前 objective 似乎是匹配行计数的集合;否则 OP 应该更新问题以说明所需的输出(例如,打印整行?打印列的子集?)
修改 OP 的示例输入以提供匹配和不匹配的混合:
$ cat input.dat
Pepper1.55ch01 PGA1.55 gene 63209 63880 . - . ID=CA01g00010;Name=CA01g00010
Pepper1.55ch01 PGA1.55 exon 63209 63880 . - . ID=CA01g00010; skipme; Name=CA01g00010
Pepper1.55ch01 PGA1.55 gene 63209 63300 . - . skipme; ID=CA01g00010:1;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 CDS 63758 63880 . - 0 ID=CDS:CA01g00010:3;Parent=mRNA.CA01g00010
Pepper1.55ch01 PGA1.55 gene 112298 112938 . - . ID=CA01g00020;Name=CA01g00020
Pepper1.55ch01 PGA1.55 exon 112298 112457 . - . ID=exon:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 gene 112298 112938 . - . ID=DE03g00230; skipme; Name=CA01g00020
Pepper1.55ch01 PGA1.55 exon 112298 112457 . - . ID=exon:CA01g00020:1;Parent=mRNA.CA01g00020
Pepper1.55ch01 PGA1.55 gene 63209 63880 . - . ID=CA01g00010;Name=CA01g00010
Pepper1.55ch01 PGA1.55 exon 63209 63880 . - . ID=CA01g00010; skipme; Name=CA01g00010
一个 awk
替代 OP 当前 awk|grep|wc
代码的想法:
awk -F'\t' -v col3="${col3}" -v id="${id}" ' # allow OP to define search strings for column 3 and the "ID=" match in column 9
== col3 && match(,"ID="id";")==1 { cnt++ } # if we find both matches then increment our counter
END { print cnt+0 } # "+0" to force default value from empty string to 0
' input.dat
对于 bash
变量 col3='gene'
和 id=CA01g00010
我们得到:
2
对于 bash
变量 col3='gene'
和 id='DE03g00230'
我们得到:
1
对于 bash
变量 col3='gene'
和 id='findme'
我们得到:
0