假设有一个文件 -
a
b
b
b
b
c
c
d
d
d
我希望根据频率对输出进行排序(我希望重复的行也被打印出来) -
b
b
b
b
d
d
d
c
c
a
答案1
使用 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
只是按正确的次数打印当前选定的行。
笔记:
- 每个字符都很重要。一行和带有额外尾随空格的同一行是不同的。
答案2
下面的操作将实现您想要的效果...不过还有许多其他方法可以实现这一点...例如gawk
,按照卡米尔 (Kamil) 的回答。
- 第一个
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