AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 529493
Accepted
R-MASHup
R-MASHup
Asked: 2019-07-11 22:42:34 +0800 CST2019-07-11 22:42:34 +0800 CST 2019-07-11 22:42:34 +0800 CST

提取字符串的一部分的最简单方法?

  • 772

我有一个文件(bigfile.txt),其中一列看起来像这样

NW_017095471.1  Gnomon  mRNA    108321  109565  .   +   .   ID=rna34;Parent=gene27;Dbxref=GeneID:108565285,Genbank:XM_017925071.1;Name=XM_017925071.1;gbkey=mRNA;gene=LOC108565285;model_evidence=Supporting evidence includes similarity to: 7 Proteins%2C and 100%25 coverage of the annotated genomic feature by RNAseq alignments%2C including 30 samples with support for all annotated introns;product=transmembrane protein 126A;transcript_id=XM_017925071.1
ID=gene27;Dbxref=GeneID:108565285;Name=LOC108565285;gbkey=Gene;gene=LOC108565285;gene_biotype=protein_coding
ID=gene28;Dbxref=GeneID:108569527;Name=LOC108569527;gbkey=Gene;gene=LOC108569527;gene_biotype=protein_coding
ID=gene78;Dbxref=GeneID:108562956;Name=LOC108562956;gbkey=Gene;gene=LOC108562956;gene_biotype=protein_coding

我有一个单独的列表:

gene27
gene28

我想获取每一行并 grep ID 字段,然后返回“Name =”后面的“LOC#”。

gene=$line
`grep $gene";" bigfile.txt | sed -e 's/Name=

返回

LOC108565285
LOC108569527

我该如何去提取这部分?

awk sed
  • 7 7 个回答
  • 744 Views

7 个回答

  • Voted
  1. Kusalananda
    2019-07-11T23:14:10+08:002019-07-11T23:14:10+08:00

    假设这是GFF 文件的第 9 个制表符分隔字段(“属性”字段),您可以提取与特定属性(从单独的文件中读取)gene对应的属性值,如下所示:IDawk

    BEGIN { FS = "\t" }
    
    FNR == NR {
        # Read IDs into a hash as keys.
        ids[$1] = 1
        next
    }
    
    $3 == "gene" {
        # Split the attribute field into separate key-value pairs.
        n = split($9, keyvalues, ";")
    
        id = ""    # Not found a gene ID yet
        gene = ""  # No gene name to print
    
        # Loop over the key-value pairs, split them on the "="
        # and extract the gene name and gene ID.
        for (i = 1; i <= n; ++i) {
            split(keyvalues[i], attr, "=")
            if (attr[1] == "ID") {
                if (attr[2] in ids)
                    id = attr[2]
                else
                    next  # This line is not of interest
            }
            else if (attr[1] == "gene")
                gene = attr[2]
        }
    
        if (id != "" && gene != "")
            print gene
    }
    

    在一个名为 GFF 的文件上运行它,该文件file.gff包含第 9 列中的给定数据,基因 ID 列表位于id.list:

    $ awk -f script.awk id.list file.gff
    LOC108565285
    LOC108569527
    

    FNR == NR基因 ID 列表是从代码块中的第一个文件中读取的awk,而最后一个块正在处理命令行中给出的第二个(以及所有以后的)文件中的基因特征行的属性字段(仅)。

    该awk代码假定 GFF 文件的ID和gene属性仅包含单个值(不是逗号分隔的值列表)并且这些值没有被引用。

    要将输出作为基因名称和基因 ID 列表(两列),请将print gene语句更改为print id, gene.

    • 2
  2. Valentin Bajrami
    2019-07-11T23:13:46+08:002019-07-11T23:13:46+08:00

    这需要重构,但应该做你想做的事:

    while IFS=; read -r line; do grep -Fw "$line" biffile.txt; done < other_file | awk -F';' '{split($3,a,"=");print a[2]}'
    
    • 0
  3. terdon
    2019-07-12T02:17:14+08:002019-07-12T02:17:14+08:00

    我会使用稍微不同的方法。首先,只提取 ID 和 Name 字段:

    $ sed -nE 's/.*ID=([^;]*).*Name=([^;]*).*/\1 \2/p' file1
    gene27 LOC108565285
    gene28 LOC108569527
    gene78 LOC108562956
    

    然后,使用目标 ID 列表过滤:

    $ cat file2
    gene27
    gene28
    $ sed -nE 's/.*ID=([^;]*).*Name=([^;]*).*/\1 \2/p' file1 | grep -wf file2 
    gene27 LOC108565285
    gene28 LOC108569527
    

    或者,如果你只想要这个LOC....值,并假设你有 GNU grep:

    $ grep -wf file2 file1 | grep -oP 'Name=\K[^;]+'
    LOC108565285
    LOC108569527
    
    • 0
  4. Philippos
    2019-07-12T23:06:08+08:002019-07-12T23:06:08+08:00

    安全的。简单的。短的。

    顾名思义bigfile.txt,我们不想 grep 多次通过它,而是一次性完成。所以我更喜欢@Kusalananda 之类的尝试:收集所有基因 ID 以提取,而不是扫描一次bigfile. 对于我更喜欢​​这样的任务sed,因为您不需要处理变量、数组和循环之类的编程,只需让工具完成工作:

    sed '/^gene[0-9]*$/{s/$/;/;H;d;};G;/ID=\(gene[0-9]*;\).*\n\1/!d;s/.*gene=\(LOC[0-9]*\);.*/\1/' genelist.txt bigfile.txt
    

    这是解释:

    • /^gene[0-9]*$/是一种选择列表行的模式:仅gene带有一个数字
    • {s/$/;/;H;d;}仅对上面的行执行:s/$/;/附加 a ;,H将此修改的行附加到保留空间并d停止进一步处理并删除该行
    • 在脚本的这一点上,我们知道我们在bigfile.txt并且保存空间充满了所有基因ID。现在G将此列表附加到模式空间
    • 该模式/ID=\(gene[0-9]*;\).*\n\1/选择在换行符之后gene[0-9]*重复 ID 的行(\1指的是第一对中的字符串\(\)),因此 ID 存在于列表中
    • !d反转选择并删除,所有没有匹配的行都被删除
    • 现在对于所有匹配的行,提取gene字段:s/.*gene=\(LOC[0-9]*\);.*/\1/
    • 0
  5. Praveen Kumar BS
    2019-07-16T07:57:04+08:002019-07-16T07:57:04+08:00

    通过以下简单脚本完成

    命令

    for i in `cat file2`; do awk -v i="$i" -F ";" '$1=="ID="i{print $5}' file1| awk -F  "=" '{print $NF}'; done
    

    输出

    LOC108565285
    LOC108569527
    
    • 0
  6. SJ7
    2020-12-26T09:07:15+08:002020-12-26T09:07:15+08:00

    尝试这个

    grep "ID=gene[0-9]" bigfile.txt |  sed 's/\;/ /g' | awk '{print $3}' | sed 's/Name=//g'
    
    • -1
  7. Best Answer
    Siva
    2019-07-11T23:04:14+08:002019-07-11T23:04:14+08:00

    尝试这个,

        grep "ID=$pattern;" file | grep -o 'Name=[^;]*' | sed 's/Name=//g';
    
    • grep -o 'Name=[^;]*'使用 grep 模式以 "Name=" 开头并立即结束 ";"
    • sed 's/Name=//g';只需根据您的要求删除不需要的模式。
    • -2

相关问题

  • 如何改进这个字符转换脚本?

  • 如何删除两行之间的单行

  • 重新排列字母并比较两个单词

  • 多行文件洗牌

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve