Linux 使用awk计算一个单词在列中出现的次数

Linux 使用awk计算一个单词在列中出现的次数,linux,bash,awk,Linux,Bash,Awk,我正在尝试使用awk来计算在一个命令中出现的单词“block”和“access”的次数 起初我试过“阻塞”这个词,但我的计数器似乎不工作。有人能看出我的代码哪里错了吗 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”的次数

起初我试过“阻塞”这个词,但我的计数器似乎不工作。有人能看出我的代码哪里错了吗

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 ' BEGIN {count=0;}  { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log

如果您特别想要“block”:
END{print count[“block”]}

您的代码可能无法工作的原因是
END
区分大小写,因此脚本将检查变量
END
是否存在(它不存在),因此最后一个块将永远不会执行。 如果你改变了这一点,那么它应该会起作用

此外,您不需要
BEGIN
块,因为所有变量都在0处实例化

下面我添加了一种替代方法,您可能希望使用它

这与glenn的类似,但只捕获您想要的单词,因此应该使用很少的内存


使用Gawk(用于匹配的第三个参数)

仅当第三个字段中包含
block
ALLOW
时,才会执行此块。
匹配捕获已匹配到数组b中的内容。
然后对匹配的字段增加数组a

END
块中,每个捕获的字段都输出一个发生计数


输出是

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

awk
调用中的错误是,在“END”块中,您有
print$count
。它获取
count
变量的内容,假设它是一个整数,并尝试在最后一行输入中找到相应的字段。您真正想要的只是
print count
,因为它只打印
count
变量中的值。有时很容易在
bash
awk
python
等之间混淆不同的变量引用方案,因此很容易犯错误。

这里是一个非代码解决方案。您可以使用管道(“|”)将步骤串在一起

  • awk'{print$3}'

    打印第三列,awk中的默认记录分隔符为空白

  • 排序

    对结果进行排序

  • uniq-c

    计算重复出现的次数


我测试了你的陈述

awk '{print $3}' file | sort | uniq -c
并且能够通过做两次更改成功计数

  • end
    应使用大写字母
  • 打印$count
  • 因此,它应该是:

    awk ' BEGIN {count=0;}  { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log
    
    一个更简单的说法也是有效的:

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

    原因是您只需要打印count而不是$count。在awk中,您不需要使用$来查找变量。在您的情况下,awk将尝试在结束前打印$2,但不会退出。下面的代码应该可以工作:


    awk'BEGIN{count=0;}{if($3==“BLOCK”)count+=1}END{print count}防火墙。log

    你的意思是允许而不是访问吗?嗨,我如何根据count[word]获取信息?例如,如果我想grep count[word]大于2的行@glenn Jackman您将在结尾块的
    for
    循环中添加
    if
    语句。我们可以检查块字百分比吗?可以。你是怎么开始的?这正是我需要的。uniq对我来说不见了,呵呵:)P.S.排序-n也是很好的,自然排序。
    awk ' BEGIN {count=0;}  { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log
    
    awk ' BEGIN {count=0;}  { if ($3 == "BLOCK") count+=1} END {print count}' firewall.log 
    
    awk '($3 == "BLOCK") {count++ } END { print count }' firewall.log