【问题标题】:extracting names from a jumbled up file从混乱的文件中提取名称
【发布时间】:2014-09-05 23:20:55
【问题描述】:

我有一个如下所示的文本文件:

MODIFIER|||c.72+1731G>T|SAMD11|protein_coding|CODING|NM_152486.2|2)
MODIFIER|||c.73-597G>A|SAMD11|protein_coding|CODING|NM_152486.2|2)
MODIFIER|||c.306-249T>C|SAMD11|protein_coding|CODING|NM_152486.2|4)
MODIFIER||2842||SAMD11|protein_coding|CODING|NM_152486.2|)
MODIFIER||4854||SAMD11|protein_coding|CODING|NM_152486.2|)
MODIFIER|||c.1443+808T>C|NOC2L|protein_coding|CODING|NM_015658.3|12)
LOW|||c.889C>G|NOC2L|protein_coding|CODING|NM_015658.3|8)
LOW|||c.889T>G|NOC2L|protein_coding|CODING|NM_015658.3|8)
MODIFIER||2687||KLHL17|protein_coding|CODING|NM_198317.2|)
MODIFIER||2885||NOC2L|protein_coding|CODING|NM_015658.3|)

我想提取 SAMD11、NOC2L 和 KLHL17 等名称。

如果这些以准确的模式出现,我会使用 tr as 分割文件

tr '|' '\t' 之后将提取包含此名称信息的列。

请帮忙。

谢谢。

【问题讨论】:

  • 仅供参考,您的文件根本没有“混乱”;它只是用管道分隔,有些字段是空的。
  • I would have.. - 那是错误的方法。

标签: perl awk grep


【解决方案1】:

使用标准剪切命令提取字段

使用管道符号作为字段分隔符,并使用标准 cut 命令提取第 5 个字段。例如:

$ cut -d\| -f5 /tmp/corpus
SAMD11
SAMD11
SAMD11
SAMD11
SAMD11
NOC2L
NOC2L
NOC2L
KLHL17
NOC2L

【讨论】:

    【解决方案2】:

    你可以使用 awk,

    $ awk -F\| '{print $5}' file
    SAMD11
    SAMD11
    SAMD11
    SAMD11
    NOC2L
    NOC2L
    NOC2L
    KLHL17
    NOC2L
    

    如果要删除重复项,请将 awk 输出传递给 sort -u

    $ awk -F\| '{print $5}' file | sort -u
    KLHL17
    NOC2L
    SAMD11
    

    按照@jaypal 的建议,您可以使用下面的 awk 单行命令删除重复项。

    awk -F\| '!seen[$5]++ && $0=$5' file
    

    【讨论】:

    • 嗨,阿维纳什,你能建议我读一读吗?我可以很好地掌握 bash 中的所有技巧。
    • @AvinashRaj 对于单个命令,您可以执行 awk -F\| '!seen[$5]++ && $0=$5' file
    • 经典之作:Sed and Awk - O'Reily Media。 awk 是一种完整的编程语言,它假设文件读取循环。可以替换grepcuttailhead
    • 我不会得到那本 sed 和 awk 的书,因为您不需要一本书来了解 sed 应该用于什么(单行上的简单替换),并且 awk 最好从大量学习中学习最新版 Effective Awk Programming,第三版,作者:Arnold Robbins。要了解 bash,请尝试 Chris Johnson 的 Bash Scripting Recipes。
    【解决方案3】:

    就像Avinash Raj'sawk solution,这可以在 Perl 中完成,完全相同的方式。您还可以包含相同的重复数据删除过程:

    perl -F'\|' -lane'print $F[4] if !$seen{$F[4]}++;' yourfile.txt
    
    • !$seen{$F[4]}++ 语句为 %seen 哈希中的任何新键返回 true。
    • -a 开关是自动拆分的,-F 设置分隔符(以正则表达式的形式)。
    • -l 处理 print 的换行符,并且
    • -n 将程序代码放入 while (<>) 循环中,该循环将读取文件或标准输入。

    【讨论】:

    • 我以为你会做perl -F'\|' -lane '$seen{$F[4]}++ or print $F[4]' file:)
    • 不,我会这样做。 ;)$s{$_}++ or print for $F[4]
    • @jaypal unless $seen.. 可能会更直观,但我认为使用惯用的!$seen{..}++ 图像很好。
    • 总体上同意,但不一定适用于单行。
    【解决方案4】:

    纯 bash

    declare -A seen
    while IFS='|' read -r a b c d e f g
    do
            let seen[$e]++
    done <<'EOF'
    MODIFIER|||c.72+1731G>T|SAMD11|protein_coding|CODING|NM_152486.2|2)
    MODIFIER|||c.73-597G>A|SAMD11|protein_coding|CODING|NM_152486.2|2)
    MODIFIER|||c.306-249T>C|SAMD11|protein_coding|CODING|NM_152486.2|4)
    MODIFIER||2842||SAMD11|protein_coding|CODING|NM_152486.2|)
    MODIFIER||4854||SAMD11|protein_coding|CODING|NM_152486.2|)
    MODIFIER|||c.1443+808T>C|NOC2L|protein_coding|CODING|NM_015658.3|12)
    LOW|||c.889C>G|NOC2L|protein_coding|CODING|NM_015658.3|8)
    LOW|||c.889T>G|NOC2L|protein_coding|CODING|NM_015658.3|8)
    MODIFIER||2687||KLHL17|protein_coding|CODING|NM_198317.2|)
    MODIFIER||2885||NOC2L|protein_coding|CODING|NM_015658.3|)
    EOF
    
    printf "%s\n" "${!seen[@]}"
    

    打印

    NOC2L
    KLHL17
    SAMD11
    

    while IFS='|' read -r a b c d e f g
    do
            echo "$e"
    done <$file | something
    

    【讨论】:

    • 很好,仅供参考 .. 它需要 bash v4 用于关联数组。
    • @jaypal 是的,这是真的...在 OS X 上的第一件事是安装 macports 和新的 bash...
    • 没错,我没用过macports .. 改用homebrew:)
    【解决方案5】:

    纯 Bash One-Liner

    如果你不想使用 cutawk,你可以用 Bash 的 read builtin 做同样的想法。基本上,这会将输入字段分隔符设置为管道符号,将每一行读入名为 line 的数组;然后打印出第 5 个字段(因为数组索引从 0 开始)。

    $ while IFS='|' read -a line; do echo "${line[4]}"; done < /tmp/foo
    SAMD11
    SAMD11
    SAMD11
    SAMD11
    SAMD11
    NOC2L
    NOC2L
    NOC2L
    KLHL17
    NOC2L
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-22
      • 1970-01-01
      • 2011-11-16
      • 2018-11-08
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      相关资源
      最近更新 更多