Сортуйте та підрахуйте кількість виникнення рядків


145

У мене є Apacheлог-файл, access.logяк підрахувати кількість появи рядків у цьому файлі? наприклад, результат cut -f 7 -d ' ' | cut -d '?' -f 1 | tr '[:upper:]' '[:lower:]'є

a.php
b.php
a.php
c.php
d.php
b.php
a.php

Я хочу цього результату:

3 a.php
2 b.php
1 d.php # order doesn't matter
1 c.php 

25
| sort | uniq -c
Костас

3
| LC_ALL=C sort | LC_ALL=C uniq -c
Стефан Шазелас

ах, я ніколи не знаю, що це uniqмогло б зробити ..
Kokizzu

У вас є приклад рядка в журналі, як я думаю, це все можна зробити з awk без усіх труб.

це нормально, файл журналу 8,1 ГБ обробляється приблизно за 2 хвилини, і це зроблено наразі, більше це не потрібно: 3
Kokizzu

Відповіді:


196
| sort | uniq -c

Як зазначено в коментарях.

Підключення виводу до sortвпорядковує вихід в алфавітному / числовому порядку.

Це вимога, оскільки відповідає uniqлише повторним рядкам, тобто

a
b
a

Якщо ви використовуєте uniqцей текстовий файл, він поверне наступне:

a
b
a

Це тому, що два as розділені між собою b- вони не є послідовними рядками. Однак якщо ви спочатку сортуєте дані в алфавітному порядку

a
a
b

Потім uniqбуде видалено рядки, що повторюються. -cВаріант uniqпідрахунку числа копій і забезпечує висновок у вигляді:

2 a
1 b

Список літератури:


1
Ласкаво просимо до Unix & Linux :) Не соромтеся додати більше деталей у свою відповідь та пояснити, чому і як це працює;)
Джон У. Сміт

1
printf '%s\n' ①.php ②.php | sort | uniq -cдарує мені2 ①.php
Стефан Шазелас

@ StéphaneChazelas Thats тому, що printf друкуєphp\nphp

4
@ Jidder, ні, це тому, що ①.phpсортує так само, як ②.phpу моїй мові, тому що для них та символів у мові не визначений порядок сортування . Якщо ви хочете отримати унікальні значення для будь-яких значень байтів (пам'ятайте, що шляхи до файлу не обов'язково є текстовими), тоді вам потрібно виправити локаль на C : | LC_ALL=C sort | LC_ALL=C uniq -c.
Стефан Шазелас

2
Щоб сортувати отриманий файл підрахунку, слід розглянути можливість додавання "sort -nr" як відповіді @ eduard-florinescu нижче.
Lluís Suñol

104
[your command] | sort | uniq -c | sort -nr

Прийнята відповідь майже завершена, ви можете додати додаткову інформацію sort -nrв кінці, щоб сортувати результати за рядками, які найчастіше зустрічаються першими

параметри uniq :

-c, --count
       prefix lines by the number of occurrences

параметри сортування :

-n, --numeric-sort
       compare according to string numerical value
-r, --reverse
       reverse the result of comparisons

У конкретному випадку, якщо ви сортуєте рядки - це цифри, які вам потрібно використовувати sort -grзамість sort -nr, див. Коментар


3
Дуже дякую, що повідомили про -nваріант.
Сигур

2
Великий відповідь, ось що я використовую , щоб отримати WordCount з файлу з пропозиціями: tr ' ' '\n' < $FILE | sort | uniq -c | sort -nr > wordcount.txt. Перша команда замінює пробіли новими рядками, дозволяючи решті команд працювати так, як очікувалося.
Бар

2
Використовуючи наведені вище параметри, я отримую "1" перед "23344". Використання sort -grзамість цього вирішує це. -g: порівняння за загальним числовим значенням (замість -n: порівняння відповідно до числового значення рядка).
Петро Ярич

@PeterJaric Чудовий улов і дуже корисно знати, -grале я думаю, що результат uniq -cбуде таким, який sort -nrбуде працювати за призначенням
Едуард Флоринеску,

3
Насправді, коли дані є цифрами, -grпрацює краще. Спробуйте ці два приклади, розрізняючи лише прапори g та n: echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -nrі echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -gr. Перший сортує неправильно, але не другий.
Петро Ярич

9

Ви можете використовувати асоціативний масив на awk, а потім -опціонально- сортувати :

cat access.log  | awk ' { tot[$0]++ } END { for (i in tot) print tot[i],i } ' | sort

вихід:

1 c.php
1 d.php
2 b.php
3 a.php

Як би ви порахували кількість випадків, коли труба надсилає дані?
користувач123456
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.