-1

Представь, что есть файл -

a
b
b
b
b
c
c
d
d
d

Я хочу, чтобы выходные данные были отсортированы по частоте (я хочу, чтобы дублирующиеся строки также печатались), а также -

b
b
b
b
d
d
d
c
c
a

2 ответа2

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
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 - просто печатать выбранную строку нужное количество раз.

Замечания:

  • Каждый персонаж имеет значение. Строка и та же строка с дополнительным пробелом различаются.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .