【问题标题】:for each unique value in a column extract lines and save separately对于列中的每个唯一值,提取行并单独保存
【发布时间】:2020-06-11 07:28:40
【问题描述】:

有没有办法分别提取具有相似值的行并分别保存? 我的文件如下

319 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Babesia;Babesia;Babesia_canis_canis;AY072926.1.1714;    88e823b2-69c5-4be5-9338-f5ce58c41ae0
443 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Babesia;Babesia;Babesia_conradae;AF158702.1.1717;   01a792e5-de00-43bb-9918-8d692a7b3226
355 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Babesia;Babesia;Babesia_duncani;HQ285838.1.1768;    1a9762a7-b4aa-4824-a416-5986d62a43e2
313 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Babesia;Babesia;Babesia_duncani;HQ285838.1.1768;    1c89bfe3-3cff-4c29-b8c9-1bc2801106b7
464 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Babesia;Babesia;Babesia_duncani;HQ285838.1.1768;    2a16a0ca-7395-4c82-8c76-13ee3121a177
419 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Babesia;Babesia;Babesia_duncani;HQ285838.1.1768;    459673b9-73a8-4044-9c0e-df30fae71ac7
321 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Theileria;Theileria;Theileria_annulata;AY508467.1.1741; 4c8b0eb7-31fe-4001-bdf2-9c75b55cce13
307 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Theileria;Theileria;Theileria_annulata;DQ287944.1.1732; 0bbaa64e-9b4d-4891-88df-dadaacbfa10c
481 Eukaryota;Alveolata;Apicomplexa;Aconoidasida;Piroplasmorida;Theileria;Theileria;Theileria_annulata;KT367879.1.1727; 0f12631e-1004-4b59-af15-11f9fa387efa

我想要的结果是为每个唯一的第二列提取所有行的第三列:

Babesia_canis_canis 的文件 1;

88e823b2-69c5-4be5-9338-f5ce58c41ae0

Babesia_conradae 的文件 2;

01a792e5-de00-43bb-9918-8d692a7b3226

Babesia_duncani 的文件 3;

1a9762a7-b4aa-4824-a416-5986d62a43e2
1c89bfe3-3cff-4c29-b8c9-1bc2801106b7
2a16a0ca-7395-4c82-8c76-13ee3121a177
459673b9-73a8-4044-9c0e-df30fae71ac7

Theileria_annulata 的文件 4;

4c8b0eb7-31fe-4001-bdf2-9c75b55cce13
0bbaa64e-9b4d-4891-88df-dadaacbfa10c
0f12631e-1004-4b59-af15-11f9fa387efa

我尝试了 awk,但无法分离文件:

awk '{c[$2]++; a[$2]=a[$2]?a[$2]RS$0:$0}
END{for(k in a) if(c[k]>1) print a[k]}' file

【问题讨论】:

  • 如何计算列数?我很困惑。

标签: awk sed


【解决方案1】:

您的方法似乎有效,但并不完全。您需要根据唯一标识符名称索引awk 中的数组。例如Babesia_canis_canis。在; 分隔符上拆分第二列并提取arrn-2th 索引处的值将具有唯一键。

awk '{
    n = split($2, arr, ";")
    key = arr[n - 2]
    unique[key] = unique[key] ? unique[key] RS $NF : $NF
}

END {
    for (id in unique) {
        print unique[id] > id
    }
    close(id)
}' file

应该在任何awk 上工作,因为没有使用 GNU 特定的构造。通过减少写入次数,这在磁盘 I/O 方面非常有效,但将每一行的内容存储在内存中。

【讨论】:

  • 我看到您只是在修复问题中提供的 OP。但请注意,这种方法会消耗大量内存(或多或少是输入文件的大小)
【解决方案2】:

像这样:

awk -F'[; ]*' '{fn=$(NF-2);print $NF >> fn; close(fn)}' input_file

请注意,每次使用后我都会明确关闭文件描述符。我这样做是为了避免遇到太多打开的文件描述符,以防有许多不同的输出文件。如果 input_file 按输出文件名排序,就像在您的示例中一样,这是多余的,但除非这对性能至关重要,否则它也不会受到伤害。如果是这种情况,请考虑将其删除。

【讨论】:

    【解决方案3】:

    这可能对你有用(GNU sed):

    sed -n 's/.*;\(.*\);.*;\s*\(\S\+\).*/echo "\2" >> "\1".txt/e' file
    

    将每一行的第二列数据附加到一个文件中,该文件由倒数第二个和倒数第二个;之间的第一列中的字符串指示。

    【讨论】:

      猜你喜欢
      • 2016-09-04
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      • 2019-04-13
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      相关资源
      最近更新 更多