【问题标题】:How can I filter through my groups/clusters to keep only the ones with different column2 values?如何过滤我的组/集群以仅保留具有不同 column2 值的组/集群?
【发布时间】:2015-06-25 21:40:43
【问题描述】:

我有一个看起来像这样的文件:

1   Ape 5138150 5140933
1   Ape 4289 7147
1   Ape 2680951 2683603
1   Ape 1484200 1486662
1   Baboon 3706008 3708636
1   Baboon 11745108 11747790
1   Baboon 3823683 3826474

2   Dog 216795245 216796748
2   Dog 14408 15922

3   Elephant 18 691
3   Ape 1 824

4   Frog 823145 826431
4   Sloth 35088 37788
4   Snake 1071033 1074121

5   Tiger 997421 1003284
5   Tiger 125725 131553

6   Tiger 2951524 2953649
6   Lion 178820 180879

每个组(或集群)由行号表示(例如,所有以 1 开头的行都在第 1 组中)并且不同的组用空行分隔,如上所示。我对第 2 列感兴趣。我想在第 2 列中保留至少有两种不同动物的所有组,但删除只有一种动物的所有组(即特定于物种的组)。所以有了这个文件,我想去掉第 2 组和第 5 组,但保留其他:

1   Ape 5138150 5140933
1   Ape 4289 7147
1   Ape 2680951 2683603
1   Ape 1484200 1486662
1   Baboon 3706008 3708636
1   Baboon 11745108 11747790
1   Baboon 3823683 3826474

3   Elephant 18 691
3   Ape 1 824

4   Frog 823145 826431
4   Sloth 35088 37788
4   Snake 1071033 1074121

6   Tiger 2951524 2953649
6   Lion 178820 180879

有没有快速/简单的方法来做到这一点?我的实际文件有超过 10,000 个不同的组,因此手动操作不是(明智的)选择。我觉得我应该能够用 awk 做到这一点,但到目前为止还没有运气。

【问题讨论】:

  • 它必须是 bash/unix/awk 解决方案还是也可以接受 python?
  • 任何解决方案都会很棒哈哈!我只是比 python 更熟悉 bash,因此标签

标签: bash unix awk


【解决方案1】:

使用 GNU awk 获取 length(array):

$ cat tst.awk
BEGIN { RS=""; ORS="\n\n"; FS="\n" }
{
    delete keys
    for (i=1; i<=NF; i++) {
        split($i,f," ")
        keys[f[2]]
    }
}
length(keys) > 1

$ awk -f tst.awk file
1   Ape 5138150 5140933
1   Ape 4289 7147
1   Ape 2680951 2683603
1   Ape 1484200 1486662
1   Baboon 3706008 3708636
1   Baboon 11745108 11747790
1   Baboon 3823683 3826474

3   Elephant 18 691
3   Ape 1 824

4   Frog 823145 826431
4   Sloth 35088 37788
4   Snake 1071033 1074121

6   Tiger 2951524 2953649
6   Lion 178820 180879

【讨论】:

    【解决方案2】:

    你可以用python解决它:

    group = []
    animals = set()
    
    with open('data') as f:
        for l in f:
            line = l.strip()
            if line == '':
                if len(animals) > 1:
                    for g in group:
                        print g
                    print ''
    
                group = []
                animals = set()
                continue
    
            group.append(line)
            animals.add(line.split()[1])
    
    if len(animals) > 1:
        for g in group:
            print g
    

    data 是您的输入文件的名称。

    说明:
    遍历文件的每一行。
    如果该行不是空行,我们将该行添加到组中以便以后打印。此外,我们将第二列添加到动物不同集。
    如果是空行,我们检查组中是否有不止一只动物。在这种情况下,我们打印组的所有行。在任何情况下,我们都会重置组和动物,因为我们要开始一个新组。
    如果最后一组包含多个动物并且文件不以空行结尾,则需要循环外部的行来写入最后一组。

    【讨论】:

      猜你喜欢
      • 2021-01-18
      • 2015-11-21
      • 2020-08-26
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 2018-08-29
      相关资源
      最近更新 更多