根据第一个唯一列值提取表

时间:2019-12-21 11:13:57

标签: python shell awk

我有一个大文件(2 GB),它采用表格格式,我需要根据第二列中的第一个值进行grep

Ref1    xzxzxzz00000135960.1    51.74   259 125 0   1   259 125 383 3e-85   269
Ref1    xzxzxzz00000126626.2    50.20   249 124 0   11  259 2   250 8e-79   248
Ref1    xzxzxzz00000137335.1    49.81   259 130 0   1   259 125 383 1e-78   252
Ref1    ASNP00000445420.1   49.42   259 131 0   1   259 125 383 3e-78   251
Ref1    xzxzxzz00000126626.2    52.20   349 124 0   11  259 2   250 8e-79   248
Ref1    ASNP00000445420.1   49.80   255 128 0   1   255 125 379 2e-77   249
Ref1    ASNPCAP00000013746.1    47.88   259 135 0   1   259 106 364 1e-76   243
Ref2    xzxzxzz00000108341.3    26.38   163 87  8   11  140 156 318 5e-04   43.9
Ref2    ASNP00000026303.9   26.38   163 87  8   11  140 149 311 5e-04   43.9
Ref2   xzxzxzz00000108321.3    16.38   163 87  8   11  140 156 318 5e-04   43.9
Ref2    ASNP00000108340.1   26.38   163 87  8   11  140 149 311 5e-04   43.9
Ref2    ENSLAFP00000015342.3    25.45   165 86  9   11  140 150 312 0.002   41.6

我需要从第二列获取相对于第一列值的第一个唯一字母。预期输出是这样的

Ref1    xzxzxzz00000135960.1    51.74   259 125 0   1   259 125 383 3e-85   269
Ref1    ASNP00000445420.1   49.42   259 131 0   1   259 125 383 3e-78   251
Ref1    ASNPCAP00000013746.1    47.88   259 135 0   1   259 106 364 1e-76   243
Ref2    xzxzxzz00000108341.3    26.38   163 87  8   11  140 156 318 5e-04   43.9
Ref2    ASNP00000026303.9   26.38   163 87  8   11  140 149 311 5e-04   43.9
Ref2    ENSLAFP00000015342.3    25.45   165 86  9   11  140 150 312 0.002   41.6

我尝试使用R,但是由于大小(可能是系统配置)而失败。 python或AWK有什么建议吗?

2 个答案:

答案 0 :(得分:2)

能否请您尝试以下。我相信这应该更快一些,尽管我还没有对海量数据进行测试。

awk '
{
  val=$2
  gsub(/[^a-zA-Z]+/,"",val)
}
!a[$1,val]++{
  value=(value?value ORS:"")$0
}
END{
  print value
}
' Input_file

输出如下。

Ref1    xzxzxzz00000135960.1    51.74   259 125 0   1   259 125 383 3e-85   269
Ref1    ASNP00000445420.1   49.42   259 131 0   1   259 125 383 3e-78   251
Ref1    ASNPCAP00000013746.1    47.88   259 135 0   1   259 106 364 1e-76   243
Ref2    xzxzxzz00000108341.3    26.38   163 87  8   11  140 156 318 5e-04   43.9
Ref2    ASNP00000026303.9   26.38   163 87  8   11  140 149 311 5e-04   43.9
Ref2    ENSLAFP00000015342.3    25.45   165 86  9   11  140 150 312 0.002   41.6

答案 1 :(得分:1)

Python版本,使用re模块和itertools.groupby

如果从您的问题中输入了data.txt,则此脚本:

import re
from itertools import groupby

with open('data.txt', 'r') as f_in:
    for v, g in groupby(f_in, lambda k: k.split()[0]):
        seen = set()
        for line in g:
            alpha = re.findall(r'^[a-zA-Z]+', line.split()[1])[0]
            if alpha not in seen:
                seen.add(alpha)
                print(line.strip())

产生:

Ref1    xzxzxzz00000135960.1    51.74   259 125 0   1   259 125 383 3e-85   269
Ref1    ASNP00000445420.1   49.42   259 131 0   1   259 125 383 3e-78   251
Ref1    ASNPCAP00000013746.1    47.88   259 135 0   1   259 106 364 1e-76   243
Ref2    xzxzxzz00000108341.3    26.38   163 87  8   11  140 156 318 5e-04   43.9
Ref2    ASNP00000026303.9   26.38   163 87  8   11  140 149 311 5e-04   43.9
Ref2    ENSLAFP00000015342.3    25.45   165 86  9   11  140 150 312 0.002   41.6