Использование awk для подсчета количества вхождений слова в столбец

03/03/2014 12:31:21 BLOCK 10.1.34.1 11:22:33:44:55:66

03/03/2014 12:31:22 ALLOW 10.1.34.2 AA:BB:CC:DD:EE:FF

03/03/2014 12:31:25 BLOCK 10.1.34.1 55:66:77:88:99:AA

Я пытаюсь использовать awk для подсчета числа вхождений слова "блок" и "доступ" выше в одной команде.

Сначала я попробовал слово "блок", но мой счетчик не работает. Может ли кто-нибудь увидеть, где мой код неправильный?

awk ' BEGIN {count=0;}  { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log

Ответ 1

Использовать массив

awk '{count[$3]++} END {for (word in count) print word, count[word]}' file

Если вы хотите "блокировать" конкретно: END {print count["BLOCK"]}

Ответ 2

Вот не -c ода решение. Вы можете связать шаги вместе с pipeми ("|").

awk '{print $3}' file | sort | uniq -c
  • awk '{print $ 3}'
    напечатайте 3-й столбец, разделителем записей по умолчанию в awk является пробел.

  • сортировать
    отсортировать результаты

  • uniq -c
    посчитать количество повторений

Ответ 3

Причина, по которой ваш код может не работать, END чувствителен к регистру, поэтому ваш script будет проверять переменную END существует (а это не так), и поэтому последний блок никогда не будет выполнен. Если вы измените это, тогда он должен работать.

Также вам не нужен блок BEGIN, поскольку вся переменная создается в 0.

Ниже я добавил альтернативный способ сделать это, который вы можете использовать вместо этого.

Это похоже на glenn, но захватывает только слова, которые вы хотите, из-за этого он должен использовать небольшую память.


Использование Gawk (для третьего аргумента соответствия)

awk 'match($3,/BLOCK|ALLOW/,b){a[b[0]]++}END{for(i in a)print i ,a[i]}' file

Этот блок выполняется только в том случае, если BLOCK или ALLOW содержатся в третьем поле.
Матч фиксирует то, что было сопоставлено с массивом b.
Затем массив a увеличивается для согласованного поля.

В блоке END каждое захваченное поле выводится со счетчиком входов.


Выходной сигнал

ALLOW 1
BLOCK 2

Ответ 4

Я проверил ваше выражение

awk ' BEGIN {count=0;}  { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log

и смог успешно подсчитать BLOCK, выполнив два изменения

  • end должен быть в шапке
  • удалить $ из print $count

Итак, это должно быть:

awk ' BEGIN {count=0;}  { if ($3 == "BLOCK") count+=1} END {print count}' firewall.log 

Более простое утверждение, которое работает также:

awk '($3 == "BLOCK") {count++ } END { print count }' firewall.log

Ответ 5

Ошибка в вашем вызове awk заключается в том, что в вашем блоке "END" у вас есть print $count. Это занимает содержимое переменной count, предполагает, что оно является целым числом, и пытается найти соответствующее поле в последней строке ввода. То, что вам действительно нужно, это просто print count, так как это просто печатает значение в переменной count. Иногда бывает легко смешивать различные схемы привязки переменных между bash, awk, python и т.д., Поэтому это легко сделать.

Ответ 6

У меня есть что-то похожее -

я спрашиваю gitlab о списке запросов на слияние

curl -Ss -k --header "PRIVATE-TOKEN: $ at" "https://gitlab/api/v4/projects/111/merge_requests?state=$ 1 & create_after = $ date & target_branch = $ branch & per_page = 100 & page = 1" | jq -r '. [] | "(.iid)\t (.author.username)"

и у меня есть список таких: output:

11039 user7 11038 user6 11037 user5 11036 user4 11035 user1 11034 user3 11033 user2 11032 user1

Как посчитать, сколько запросов на слияние поднимает каждый пользователь. Как посчитать, сколько запросов растет user1, сколько user2 и т.д.

когда я делаю этот завиток как переменную: Запрос = curl -Ss -k --header "PRIVATE-TOKEN: $at" "https://gitlab/api/v4/projects/111/merge_requests?state=$1&created_after=$date&target_branch=$branch&per_page=100&page=1"| jq -r '.[] | "\(.iid)\t\(.author.username)"

и распечатайте это как:

    echo "list of $1 requests rise today"
    echo "$request"
    echo
    echo "--------stats--------------"
    echo "\n$request" | awk '/^[0-9]/{a[$2]++}END{for (i in a) print i, a[i]}'
    echo "---------------------------"
    echo

эта команда awk не показывает правильную математику для некоторых опций. Есть ли более простой вариант?

Спасибо за помощь.