首页 > 解决方案 > 根据列的相同值的计数进行分组和排序,并对这些组中的另一列进行排序

问题描述

假设我得到了这个日志文件:

100.1 500
100.2 501
100.2 501
100.2 501
100.1 501
666.2 501
300.1 555
300.1 501
100.1 300
100.1 300
100.1 300
102.3 500
202.1 500
301.2 300

应首先删除任何重复的行。然后交换列。然后根据第一列值(501、500 等)对行进行分组,根据这些值的计数对这些组进行排序。最后,按降序对此类组的第二列值进行排序。

这是我已经走了多远:

$ awk '{!seen[$2, $1]++}; END {for (i in seen) print i}' $filename |
       sort -k2 -n -r
555?300.1
501?666.2
501?300.1
501?100.2
501?100.1
500?202.1
500?102.3
500?100.1
300?301.2
300?100.1

这是预期的输出:

501 666.2
501 300.1
501 100.2
501 100.1
500 202.1
500 102.3
500 100.1
300 301.2
300 100.1
555 300.1

标签: sortingawk

解决方案


使用 GNU awk,您能否尝试关注,尽管我仍然不确定 OP 是否需要它。由于 OP 在评论中确认这有效,因此添加了一个答案并要求 OP 也相应地更改问题。

awk '
!c[$1,$2]++{
  a[$2]++
  b[$2]=(b[$2]?b[$2] ORS:"")$2 OFS $1
}
END{
  PROCINFO["sorted_in"] = "@val_num_desc"
  for(i in a){ print b[i] }
}
' Input_file

(由 Sundeep 编辑)我自己并不完全理解这一点,但这似乎适用于GNU awk

$ awk 'BEGIN{PROCINFO["sorted_in"] = "@val_num_desc"};
       !seen[$0]++{a[$2]++; b[$2][$1]}
       END{for(i in a) for(j in b[i]) print i, j}' ip.txt
501 666.2
501 300.1
501 100.2
501 100.1
500 202.1
500 102.3
500 100.1
300 301.2
300 100.1
555 300.1

推荐阅读