[英]Using awk to count the number of occurrences of a word in a column
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 來計算一個命令中上述單詞“block”和“access”的出現次數。
我一開始嘗試使用“阻止”這個詞,但我的計數器似乎不起作用。 誰能看到我的代碼錯在哪里?
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"]}
這是一個非代碼解決方案。 您可以使用管道 ( "|" ) 將步驟串在一起。
awk '{print $3}' file | sort | uniq -c
awk '{print $3}'
打印第三列,awk 中的默認記錄分隔符是空格。
sort
對結果進行排序
uniq -c
計算重復出現的次數
您的代碼可能無法正常工作的原因是END
區分大小寫,因此您的腳本將檢查變量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&created_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作為變量時:request = 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)"
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命令在某些選項上未顯示正確的數學運算。 有沒有更簡單的選擇?
感謝幫助。
原因是你只需要打印計數而不是 $count。 在 awk 中,您不需要使用 $ 來查找變量。 在您的情況下,awk 將嘗試在結束前打印 $2 並不會退出。 下面的代碼應該工作:
awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} END {print count}' firewall.log
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.