基于不同的第一列的所有列的最大值

时间:2017-07-05 15:52:22

标签: bash

如果我有两列以上,如何更改代码。假设数据是这样的

ifile.dat
1   10  15
3   34  20
1   4   22
3   32  33
5   3   46
2   2   98
4   20  100
3   13  23
4   50  65
1   40  76
2   20  22

我如何实现这一目标?

ofile.dat
1   40  76
2   20  98
3   34  33
4   50  100
5   3   46

我的意思是通过比较第一列来确定每列的最大值。感谢。

这是我尝试过的(在13个列的示例文件中)。但最高价值并非如此。

cat input.txt | sort -k1,1 -k2,2nr -k3,3nr -k4,4nr -k5,5nr -k6,6nr -k7,7nr -k8,8nr -k9,9nr -k10,10nr -nrk11,11 -nrk12,12 -nrk13,13 | sort -k1,1 -u 

1 个答案:

答案 0 :(得分:1)

您可以切换到像sort这样更强大的内容,而不是依赖awk

 awk 'BEGIN{PROCINFO["sorted_in"] = "@val_num_asc"} {for(i=2;i<=NF;++i) if (a[$1][i]<$i){a[$1][i]=$i}} END{n=asorti(a, asorted); for(col1 in asorted){print col1, a[col1][2], a[col1][3]}}' input.txt 

那是一口气。它分解如下:

  1. 在处理文件之前,将PROCINFO设置sorted_in设置为@val_num_asc,因为我们将按照索引对数组内容进行排序:{{1} })
  2. 遍历记录BEGIN{PROCINFO["sorted_in"] = "@val_num_asc"}
  3. 中的每个字段
  4. 测试当前值是否大于数组中的存储值,该数组的索引是第一个字段的值。如果它更大,则将其存储在该字段位置的该索引的数组中当前保存的任何位置:(for(i=2;i<=NF;++i)
  5. 完成处理所有记录后,将数组排序为新数组if (a[$1][i]<$i){a[$1][i]=$i} :( asorted
  6. 遍历数组并打印每个元素(END{n=asorti(a, asorted);
  7. for(col1 in asorted){print col1, a[col1][2], a[col1][3]}中可能有一种更优雅的方法可以做到这一点,但这样做会有所帮助。

    示例:

    awk