匹配后查找特定单词

Posted

技术标签:

【中文标题】匹配后查找特定单词【英文标题】:Find specific words after a match 【发布时间】:2022-01-21 04:13:35 【问题描述】:

我有一个如下所示的数据集:

chr1    StringTie   exon    197757319   197757401   1000    +   .   gene_id "MSTRG.10429"; transcript_id "ENST00000440885.1"; exon_number "1"; gene_name "RP11-448G4.4"; ref_gene_id "ENSG00000224901.1";
chr1    StringTie   exon    197761802   197761965   1000    +   .   gene_id "MSTRG.10429"; transcript_id "ENST00000440885.1"; exon_number "2"; gene_name "RP11-448G4.4"; ref_gene_id "ENSG00000224901.1";
chr9    StringTie   exon    63396911    63397070    1000    -   .   gene_id "MSTRG.145111"; transcript_id "MSTRG.145111.1"; exon_number "1";
chr9    StringTie   exon    63397111    63397185    1000    -   .   gene_id "MSTRG.145111"; transcript_id "MSTRG.145111.1"; exon_number "2";
chr21   StringTie   exon    44884690    44884759    1000    +   .   gene_id "MSTRG.87407"; transcript_id "MSTRG.87407.1"; exon_number "1";
chr22   HAVANA  exon    19667023    19667199    .   +   .   gene_id "ENSG00000225007.1"; transcript_id "ENST00000452326.1"; exon_number "1"; gene_name "AC000067.1";
chr22   HAVANA  exon    19667446    19667555    .   +   .   gene_id "ENSG00000225007.1"; transcript_id "ENST00000452326.1"; exon_number "2"; gene_name "AC000067.1";

我想隔离gene_ids。因此,期望的输出是:

MSTRG.10429
MSTRG.10429
MSTRG.145111
MSTRG.145111
MSTRG.87407
ENSG00000225007.1
ENSG00000225007.1

我尝试了以下方法:

grep -E -o "gene_id.0,20" gtf_om_ENSGids_te_vinden.gtf > alle_gene_ids.txt

有了这个我可以grep“gene_id”之后的20个字符,我想稍后删除不属于答案的其他字符,例如“transcript”这个词的一部分。但是,一个问题是 ref_gene_ids 也会被复制,这不属于所需的输出。我试图通过添加 -w 标志来解决这个问题,但由于某种原因这也是错误的。有人可以帮忙吗?

谢谢!

【问题讨论】:

【参考方案1】:

GNU grep,使用 perl 正则表达式标志:

grep -Po '(?<=\Wgene_id ")[^"]+'

POSIX sed:

sed -En 's/.*[^[:alnum:]_]gene_id "([^"]+).*/\1/p'

如果每行出现多次,grep 将打印所有这些,但 sed 将仅打印最后一次出现。

【讨论】:

【参考方案2】:

用途:

grep -o -E ' gene_id \"([^"]*)\"' gtf_om_ENSGids_te_vinden.gtf  | sed -E 's/gene_id|"| //g'
需要' gene_id 中的空格来确保ref_gene_id 不匹配。 sed 部分将删除 gene_id、空格和双引号。

见:https://regex101.com/r/TDA7Cg/1

编辑:因为选项卡不是空格:

改成

grep -o -E '[ \t]gene_id \"([^"]*)\"' gtf_om_ENSGids_te_vinden.gtf  | sed -E 's/gene_id|"| //g'

或者只是找到你可以找到的单词的开头

grep -o -E '\Wgene_id \"([^"]*)\"' gtf_om_ENSGids_te_vinden.gtf  | sed -E 's/gene_id|"| //g'

但接受的答案仍然是一种更好的方法......?

【讨论】:

谢谢,但是,这还行不通,我认为是因为在“gene_id”部分前面使用的不是空格而是制表符。当我使用这样的代码时,我没有收到任何输出

以上是关于匹配后查找特定单词的主要内容,如果未能解决你的问题,请参考以下文章

在bash中匹配单词后的一行中打印特定字符串[重复]

在字符串中查找与字典中的值匹配的单词,然后在新列中返回键

如何在没有意外匹配的情况下在 PHP 中的字符串中查找整个单词?

Java如何找到一个单词的每一次匹配?

如何在 Go 中列出所有匹配的进程? [关闭]

正则表达式 - 匹配任何单词但忽略特定单词[重复]