使用awk计算列中单词出现次数

时间:2015-01-16 14:43:39

标签: linux bash 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在一个命令中计算上面“block”和“access”一词的出现次数。

我最初尝试过“阻止”这个词,但我的计数器似乎没有工作。任何人都可以看到我的代码出错了吗?

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

6 个答案:

答案 0 :(得分:26)

使用数组

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

如果你想特别想要“阻止”:END {print count["BLOCK"]}

答案 1 :(得分:11)

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

awk '{print $3}' file | sort | uniq -c
  • awk'{print $ 3}'
    打印第3列,awk中的默认记录分隔符为空格。

  • 排序
    对结果进行排序

  • uniq -c
    计算重复出现次数

答案 2 :(得分:4)

您的代码可能无法正常工作的原因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

只有在第三个字段中包含BLOCKALLOW时才会执行此块 该匹配捕获已匹配到阵列b中的内容 然后,对于匹配的字段,数组a递增。

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


输出

ALLOW 1
BLOCK 2

答案 3 :(得分:3)

我测试了你的陈述

<?php
if (!defined('TYPO3_MODE')) {die('Access denied.');}

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('code', 'Configuration/TypoScript', 'Description');

并且能够通过两次更改成功计算awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log

  1. BLOCK应该是大写
  2. end
  3. 中移除$

    所以,它应该是:

    print $count

    一个更简单的陈述也是:

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

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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

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