按“行内容”频率对文件进行排序 - 打印重复项


-1

想象一下有一个档案 -

a
b
b
b
b
c
c
d
d
d

我想根据频率对输出进行排序(我也想要打印重复的行) -

b
b
b
b
d
d
d
c
c
a

Answers:


3

使用GNU Awk:

gawk '
   { arr[$0]++ }
   END {
        PROCINFO["sorted_in"] = "@val_num_desc"
        for (ln in arr) for (i = 1; i <= arr[ln]; i++) print ln
       }
   '

诀窍是使用数组和@val_num_desc。每个遇到的行都成为一个索引,每次出现该行时,相关的值都会增加。最后,我们按特定顺序扫描整个数组:

"@val_num_desc"
[...]作为数字处理的元素值按从高到低的顺序排序。

资源

所以外(第一)for负责按所需顺序检索线路及其频率; 内部(第二个)for只是打印当前拾取的行正确的次数。

注意:

  • 每个角色都很重要 一条线和具有额外尾随空格的同一条线是不同的。

PROCINFO["sorted_in"]- 太棒了,正是我想要做的一个awk例子,谢谢!
Attie

3
@Attie我认为它可能无法正常工作awk,除非你awkgawk伪装的。在我的Debian awk过去有限,我不得不安装gawk。现在两个命令都理解这个,因为awk(非直接)符号链接到gawk
Kamil Maciorowski

3

以下将做你想要做的事情......虽然有许多其他方法可以实现这一点......例如gawk,根据卡米尔的回答。

  • 第一个sort将按行数据排序数据
  • uniq -c 将计算匹配事件的数量(它们必须是邻居)
  • sort -nr 将按相反的顺序按出现次数排序
  • while在每行循环迭代
    • read n l将计数摄入n,并将行数据导入l
  • for循环将遍历n
  • echo "${l}" 输出行数据
(
    sort \
        | uniq -c \
        | sort -nr \
        | while read n l; do \
            for i in $(seq ${n}); do \
                echo "${l}"; \
            done; \
        done
) <<"EOF"
a
b
b
b
b
c
c
d
d
d
EOF
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.