代码之家  ›  专栏  ›  技术社区  ›  Rohan Nath

如何使用Bash命令提取具有多行的簇?

  •  0
  • Rohan Nath  · 技术社区  · 3 月前

    我正在尝试使用Bash命令从文本文件中提取集群。每个簇由以>簇我只想提取那些包含多个数据行的集群。以下是我的输入文件的简化示例:

    >Cluster 199
    0       2599aa, >CAD5117741.1... *
    >Cluster 200
    0       2579aa, >CAD5112262.1... *
    >Cluster 201
    0       2578aa, >CAD5116287.1... *
    >Cluster 202
    0       2578aa, >CAD5122864.1... *
    1       1867aa, >CAD5122865.1... at 100.00%
    2       2369aa, >CAD5122866.1... at 100.00%
    >Cluster 203
    0       2573aa, >CAD5110750.1... *
    >Cluster 204
    0       2571aa, >CAD5116249.1... *
    >Cluster 205
    0       2558aa, >CAD5122682.1... *
    >Cluster 206
    0       2553aa, >CAD5126525.1... *
    >Cluster 207
    0       2551aa, >CAD5115834.1... *
    

    在这个例子中,我只想提取集群202,因为它里面有多行数据。所需的输出是:

    >Cluster 202
    0       2578aa, >CAD5122864.1... *
    1       1867aa, >CAD5122865.1... at 100.00%
    2       2369aa, >CAD5122866.1... at 100.00%
    

    我目前正在使用awk处理文件,但很难弄清楚如何正确提取这些集群。有人能指导我使用Bash命令高效地完成这项任务吗?

    我尝试使用以下awk命令:

    awk '/^>Cluster/ {cluster=$0; count=0; next} {count++} count > 1 {print cluster; print} count == 0 {print cluster}'
    

    当应用于所提供的数据时,它会产生以下输出:

    >Cluster 202 2 2369aa, >CAD5122866.1... at 100.00%
    

    这个输出是不完整的,因为它应该包括簇202内的所有行。

    3 回复  |  直到 3 月前
        1
  •  2
  •   Antonio Petricca    3 月前

    这是一个简单的工作脚本(刚刚测试过,没有 awk ):

    #!/bin/bash
    
    function process_cluster {
        
        input_file=$1
        current_cluster=""
        data_rows=0
    
        while read -r line; do
            if [[ $line == ">Cluster "* ]]; then
                if [[ $data_rows -gt 1 ]]; then
                    echo -e "$current_cluster" 
                fi
                
                current_cluster="$line"  
                data_rows=0
            else
                ((data_rows++))
                current_cluster="$current_cluster\n$line" 
            fi
        done < $input_file
    
        if [[ $data_rows -gt 1 ]]; then
            echo -e "$current_cluster"
        fi
    
    }
    
    process_cluster clusters.txt > output.txt
    

    请记住将输入数据保存到名为的文件中 clusters.txt 或者将其更改为上述脚本。

        2
  •  0
  •   Inian    3 月前

    或者在Awk中完全按照下面的1-pass进行操作。使用集群名称作为主键,并在名称后面附加内容。最后,打印所有具有多行的记录。

    awk '
    /^>Cluster/ {
        name = $0
        next
    }
    {
        content[name] = (content[name] ? (content[name] RS $0) : ($0))
        lines[name]++
    }
    END {
        for (c in content)
            if (lines[c] > 1)
                print c ORS content[c]
    }' file
    
        3
  •  0
  •   oguz ismail    3 月前

    用锥子分两次通过:

    awk '/^>/{h=$0} NR==FNR{c[h]++;next} c[h]>2' file file
    
        4
  •  0
  •   Ed Morton    3 月前

    在1次读取输入并仅存储1的过程中使用任意awk ^> -在内存中一次分离的记录:

    awk '
        /^>/ { prt(); rec=$0; next }
        { rec = rec ORS $0 }
        END { prt() }
        function prt() { if (gsub(ORS,"&",rec)>1) print rec }
    ' file
    >Cluster 202
    0       2578aa, >CAD5122864.1... *
    1       1867aa, >CAD5122865.1... at 100.00%
    2       2369aa, >CAD5122866.1... at 100.00%