【问题标题】:Find the maximum values in 2nd column for each distinct values in 1st column using Linux使用 Linux 查找第一列中每个不同值的第二列中的最大值
【发布时间】:2015-06-12 02:42:21
【问题描述】:

我有两列如下

ifile.dat
1   10
3   34
1   4
3   32
5   3
2   2
4   20
3   13
4   50
1   40
2   20

我要查找的是在第一列中的每个 1、2、3、4、5 的第二列中找到最大值。

ofile.dat
1   40 
2   20
3   34
4   50
5   3

我发现有人使用其他程序完成了此操作,例如Get the maximum values of column B per each distinct value of column A

【问题讨论】:

    标签: linux bash unix awk


    【解决方案1】:

    awk 似乎是这项任务的主要候选人。只需遍历您的输入文件并保留一个由第一列值索引的数组,如果它大于当前存储的值,则存储第 2 列的值。在遍历结束时遍历数组以打印索引和对应的值

    awk '{
        if (a[$1] < $2) {
            a[$1]=$2
        }
    } END {
        for (i in a) {
            print i, a[i]
        }
    }' ifile.dat
    

    现在结果不会在第一列按数字排序,但如果需要,应该很容易修复

    【讨论】:

    • 注意,最大值为负的第一组会失败。在测试当前值是否更大之前,您应该查看是否设置了a[$1]。在if (a[$1] &lt; $2) 之前添加if (a[$1] == "") a[$1] = $2;。
    【解决方案2】:

    另一种方法是使用排序。 第 2 列的第一个数字排序递减,然后删除第 1 列的非唯一值,单行:

    sort -n -r -k 2  ifile.dat| sort -u -n -k 1
    

    【讨论】:

      【解决方案3】:

      在第二列中找到最大值的最简单的命令是这样的

      sort -nrk2 data.txt | awk 'NR==1{print $2}'
      

      【讨论】:

        【解决方案4】:

        在进行最小/最大计算时,始终使用读取的第一个值作为最小/最大变量的种子:

        $ cat tst.awk
        !($1 in max) || $2>max[$1] { max[$1] = $2 }
        END {
            PROCINFO["sorted_in"] = "@ind_num_asc"
            for (key in max) {
                print key, max[key]
            }
        }
        
        $ awk -f tst.awk file
        1 40
        2 20
        3 34
        4 50
        5 3
        

        以上使用 GNU awk 4.* for PROCINFO["sorted_in"] 来控制输出顺序,参见http://www.gnu.org/software/gawk/manual/gawk.html#Controlling-Array-Traversal。

        【讨论】:

          【解决方案5】:

          考虑到您的第一个字段将从 1 开始,如果是,请在 awk 中尝试另一种解决方案。

          awk '{a[$1]=$2>a[$1]?$2:(a[$2]?a[$2]:$2);} END{for(j=1;j<=length(a);j++){if(a[j]){print j,a[j]}}}'   Input_file
          

          在这里也为同样添加另一种方式。

          sort -k1 Input_file | awk 'prev != $1 && prev{print prev, val;val=prev=""} {val=val>$2?val:$2;prev=$1} END{print prev,val}'
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-15
            • 1970-01-01
            相关资源
            最近更新 更多