Ответ 1
Использовать массив
awk '{count[$3]++} END {for (word in count) print word, count[word]}' file
Если вы хотите "блокировать" конкретно: END {print count["BLOCK"]}
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
Использовать массив
awk '{count[$3]++} END {for (word in count) print word, count[word]}' file
Если вы хотите "блокировать" конкретно: END {print count["BLOCK"]}
Вот не -c ода решение. Вы можете связать шаги вместе с pipeми ("|").
awk '{print $3}' file | sort | uniq -c
awk '{print $ 3}'
напечатайте 3-й столбец, разделителем записей по умолчанию в awk является пробел.
сортировать
отсортировать результаты
uniq -c
посчитать количество повторений
Причина, по которой ваш код может не работать, 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
Я проверил ваше выражение
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
Ошибка в вашем вызове awk
заключается в том, что в вашем блоке "END" у вас есть print $count
. Это занимает содержимое переменной count
, предполагает, что оно является целым числом, и пытается найти соответствующее поле в последней строке ввода. То, что вам действительно нужно, это просто print count
, так как это просто печатает значение в переменной count
. Иногда бывает легко смешивать различные схемы привязки переменных между bash
, awk
, python
и т.д., Поэтому это легко сделать.
У меня есть что-то похожее -
я спрашиваю 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 не показывает правильную математику для некоторых опций. Есть ли более простой вариант?
Спасибо за помощь.