【问题标题】:extract string between two strings of a cut result在剪切结果的两个字符串之间提取字符串
【发布时间】:2015-01-09 09:59:54
【问题描述】:

我正在使用 cut 来提取制表符分隔文件中的列:

cut -f 14 glra3res.vcf

这里的结果是:

STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC;HGNC_ID=HGNC:4326;BIOTYPE=protein_coding;CANONICAL=YES;CCDS=CCDS54942.1;ENSP=ENSP00000411593;SWISSPROT=P23415;UNIPARC=UPI0000DA6BF2;SIFT=deleterious(0.02);PolyPhen=benign(0.167);EXON=9/9;DOMAINS=Superfamily_domains:SSF90112;HGVSc=ENST00000455880.2:c.1363C>A;HGVSp=ENSP00000411593.2:p.His455Asn;AA_MAF=T:0;EA_MAF=T:0.000116
STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC;HGNC_ID=HGNC:4326;BIOTYPE=protein_coding;CCDS=CCDS4320.1;ENSP=ENSP00000274576;SWISSPROT=P23415;TREMBL=Q14C71;UNIPARC=UPI000013DA17;SIFT=deleterious(0.02);PolyPhen=benign(0.315);EXON=9/9;DOMAINS=Superfamily_domains:SSF90112;HGVSc=ENST00000274576.6:c.1339C>A;HGVSp=ENSP00000274576.4:p.His447Asn;AA_MAF=T:0;EA_MAF=T:0.000116

我想提取SYMBOL=; 之间的字符串,这将导致GLRA3

我正在尝试将其通过管道传输到 grep 命令中:

cut -f 14 glra1res.vcf | grep 'SYMBOL='

当然会选择SYMBOL=,我也可以只选择;。我很难将两者结合起来以获得它们之间的字符串。只是在做

cut -f 14 glra1res.vcf | grep 'SYMBOL=' | grep ';'

忽略SYMBOL=,我认为如果我可以同时选择这两个,那将是一个开始......

【问题讨论】:

    标签: string bash perl awk grep


    【解决方案1】:

    如果您不介意使用 sed:

    bash-3.2$ cut -f 14 myfile | sed 's/.*SYMBOL=\([^;]*\);.*/\1/g'
    GLRA3
    GLRA3
    

    并且仅使用带有-d 选项的剪切:

    bash-3.2$ cut -f 14 myfile | cut -d';' -f 2|cut -d'=' -f 2
    GLRA3
    GLRA3
    

    【讨论】:

    • 错误你有grep -Po吗?当我发布我的答案时它不在这里,现在我看到了,我不想看到我的作为你的副本:)
    • @fedorqui 你已经在我面前发帖了。但是我在完成打字后看到了你的答案。正如你比我解释得更清楚,我已经删除了 grep 部分。
    • 哦,你不必这样做。无论如何,为提供的多种解决方案 +1。
    • 我有点被这里的选择宠坏了。我对 sed 很熟悉,但也可以通过管道输入相应的剪切命令。
    【解决方案2】:

    这可以通过grep 和look-behind 来完成:

    ... | grep -Po '(?<=SYMBOL=)[^;]*'
    GLRA3
    GLRA3
    

    当它出现在SYMBOL= 之后时,它会得到[^;]*。而[^;]* 表示“在找到; 之前的任何字符集”。


    请注意,您离解决方案并不远。如果您对-o 执行以下操作,您可以打印SYMBOL= 之后的内容,直到找到;

    ... | grep -o 'SYMBOL=[^;]*'
    SYMBOL=GLRA3
    SYMBOL=GLRA3
    

    然后您可以添加-P 选项来执行\K,它会删除之前匹配的文本并只打印接下来的内容:

    ... | grep -Po 'SYMBOL=\K[^;]*'
    GLRA3
    GLRA3
    

    【讨论】:

    • 酷!不知道\K。
    【解决方案3】:

    您不需要一堆不同的命令和管道,只需要一个简单的 awk 命令。看,假设您有一个当前运行剪切的制表符分隔文件:

    $ cat file
    abc     STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC       def
    gh      STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC       ij
    
    $ cut -f2 file
    STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC
    STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC
    

    现在只需在其上运行这个 awk 脚本:

    $ awk -F'\t' '{split($2,a,/[;=]/); print a[4]}' file
    GLRA3
    GLRA3
    

    $2 更改为$14 以获得您的真实文件。

    如果“SYMBOL”并不总是在同一个位置,只需创建一个将名称映射到值的数组,并通过其名称打印您喜欢的任何值:

    $ awk -F'\t' '{split($2,a,/[;=]/); for (i=1;i in a;i+=2) n2v[a[i]]=a[i+1]; print n2v["SYMBOL"]}' file
    GLRA3
    GLRA3
    
    $ awk -F'\t' '{split($2,a,/[;=]/); for (i=1;i in a;i+=2) n2v[a[i]]=a[i+1]; print n2v["STRAND"]}' file
    -1
    -1
    
    $ awk -F'\t' '{split($2,a,/[;=]/); for (i=1;i in a;i+=2) n2v[a[i]]=a[i+1]; print n2v["SYMBOL_SOURCE"]}' file
    HGNC
    HGNC
    
    $ awk -F'\t' '{
        split($2,a,/[;=]/)
        for (i=1;i in a;i+=2) {
            n2v[a[i]]=a[i+1]
        }
        for (name in n2v) {
            print name, "->", n2v[name]
        }
    }' file
    SYMBOL -> GLRA3
    STRAND -> -1
    SYMBOL_SOURCE -> HGNC
    SYMBOL -> GLRA3
    STRAND -> -1
    SYMBOL_SOURCE -> HGNC
    

    【讨论】:

      【解决方案4】:

      你甚至可以在 perl one liner 中试试这个:

      输入文件:

      STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC;HGNC_ID=HGNC:4326;BIOTYPE=protein_coding;CANONICAL=YES;CCDS=CCDS54942.1;ENSP=ENSP00000411593;SWISSPROT=P23415;UNIPARC=UPI0000DA6BF2;SIFT=deleterious(0.02);PolyPhen=benign(0.167);EXON=9/9;DOMAINS=Superfamily_domains:SSF90112;HGVSc=ENST00000455880.2:c.1363C>A;HGVSp=ENSP00000411593.2:p.His455Asn;AA_MAF=T:0;EA_MAF=T:0.000116
      STRAND=-1;SYMBOL=GLRA3;SYMBOL_SOURCE=HGNC;HGNC_ID=HGNC:4326;BIOTYPE=protein_coding;CCDS=CCDS4320.1;ENSP=ENSP00000274576;SWISSPROT=P23415;TREMBL=Q14C71;UNIPARC=UPI000013DA17;SIFT=deleterious(0.02);PolyPhen=benign(0.315);EXON=9/9;DOMAINS=Superfamily_domains:SSF90112;HGVSc=ENST00000274576.6:c.1339C>A;HGVSp=ENSP00000274576.4:p.His447Asn;AA_MAF=T:0;EA_MAF=T:0.000116
      

      代码:(Windows 提示符)

      perl -lne "if($_ =~ /SYMBOL=(.*?[^;]);/i) { print $1;}" InputFile
      

      Shell 提示符:

      perl -lne 'if($_ =~ /SYMBOL=(.*?[^;]);/i) { print $1;}' InputFile
      

      输出:

      GLRA3
      GLRA3
      

      【讨论】:

        【解决方案5】:

        使用 perl,如果您同时拆分 ;=,您可以为每个 errm“基因”构建哈希哈希 (?) 或文件中的行。此示例使用“主题”变量$_%_ 和“autosplit”数组@F(使用-a-F 制作,有关开关的详细信息,请参阅perlrun)打印出“SYMBOL”的值" 默认的键有 (%_):

        perl -F"/;|=/" -anE '$_{$.}={@F} ;}{ say $_{$_}{SYMBOL} for keys %_' data.txt
        

        这样您就可以通过更改键来选择要打印的值 - 例如

        perl -F"/;|=/" -anE '$_{$.}={@F} ;}{ say $_{$_}{CCDS} for keys %_' data.txt
        

        当然,哈希数组也是可能的:

        perl -F"/;|=/" -anE 'push @genes, {@F} ;}{ say ${$_}{CCDS} for @genes' data.txt
        

        我发现如果我立即开始使用数据结构(即使是在单行中),可以更轻松地开始想象更长的脚本或应用程序。最好的工具之一是Data::Printer,它可以让你“看到”散列和数组:perl -MDDP -F"/;|=/" -lane '$_{$.}={@F};}{ p %_' data.txt

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-29
          • 1970-01-01
          • 1970-01-01
          • 2014-02-26
          相关资源
          最近更新 更多