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