Представь, что есть файл -
a
b
b
b
b
c
c
d
d
d
Я хочу, чтобы выходные данные были отсортированы по частоте (я хочу, чтобы дублирующиеся строки также печатались), а также -
b
b
b
b
d
d
d
c
c
a
Представь, что есть файл -
a
b
b
b
b
c
c
d
d
d
Я хочу, чтобы выходные данные были отсортированы по частоте (я хочу, чтобы дублирующиеся строки также печатались), а также -
b
b
b
b
d
d
d
c
c
a
Следующее сделает то, что вам нужно ... хотя есть много других способов добиться этого ... например, с помощью 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
С 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
- просто печатать выбранную строку нужное количество раз.
Замечания: