【问题标题】:Using awk to count the number of occurrences of a word in a column使用awk统计某列单词出现的次数
【发布时间】:2015-03-15 04:52:55
【问题描述】:
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

【问题讨论】:

  • 你的意思是允许而不是访问?

标签: linux bash awk


【解决方案1】:

使用数组

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

如果你想专门“阻止”:END {print count["BLOCK"]}

【讨论】:

  • 嗨,我如何根据 count[word] 获取信息?例如,如果我想对 count[word] 大于 2 的行进行 grep。@glenn jackman
  • 您可以将if 语句添加到END 块中的for 循环中。
  • 我们可以检查块字百分比吗?
  • 是的,我们可以。您将如何开始这样做?
【解决方案2】:

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

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

下面我添加了一种替代方法,您可能想要使用它。

这类似于 glenn's 但只捕获您想要的单词,因此它应该占用很少的内存。


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

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

仅当BLOCKALLOW 包含在第三个字段中时才会执行此块。
匹配捕获已匹配到数组 b 中的内容。
然后数组 a 为匹配的字段递增。

END 块中,每个捕获的字段都会输出出现次数。


输出是

ALLOW 1
BLOCK 2

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      awk '{print $3}' file | sort | uniq -c
      
      • awk '{print $3}'

        打印第三列,awk中默认的记录分隔符是空格。

      • sort

        对结果进行排序

      • uniq -c

        计算重复出现的次数

      【讨论】:

      • 正是我需要的。 uniq 对我来说不见了,呵呵 :) sort -n 也不错,自然排序。
      【解决方案5】:

      我测试了你的陈述

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

      并且能够通过两次更改成功计数BLOCK

      1. end 应该大写
      2. 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
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-15
          相关资源
          最近更新 更多