借助 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 个元素。

假设:

  • 不必担心不区分大小写的匹配(例如,不必匹配 GENEGene
  • 第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