首页 > 解决方案 > 使用 grep 解析非结构化文本文件

问题描述

我正在尝试分析来自 MIT 的 IDS 日志文件,在此处找到

Summarized attack: 41.084031
 IDnum    Date       StartTime Duration Destination    Attackname insider? manual? console?success? aDump? oDump iDumpBSM? SysLogs FSListing StealthyNew? Category OS
 41.08403103/29/1999 08:18:35  00:04:07 172.016.112.050ps         out              rem     succ     aDmp   oDmp  iDmp BSM  SysLg   FSLst     Stlth   Old  llU2R 
 41.08403103/29/1999 08:19:37  00:01:56 209.154.098.104ps         out              rem     succ     aDmp   oDmp  iDmp BSM  SysLg   FSLst     Stlth   Old  llU2R 
 41.08403103/29/1999 08:29:27  00:00:43 172.016.112.050ps         out              rem     succ     aDmp   oDmp  iDmp BSM  SysLg   FSLst     Stlth   Old  llU2R 
 41.08403103/29/1999 08:40:14  00:24:26 172.016.112.050ps         out              rem     succ     aDmp   oDmp  iDmp BSM  SysLg   FSLst     Stlth   Old  llU2R 

我正在尝试编写执行两件事的命令:

  1. 首先,解析整个文件并确定以 4x.xxxxx 开头的不同“汇总攻击”的数量。我已经做到了这一点: grep -o -E "Summarized attack: 4"。它返回80
  2. 其次,对于上述命令找到的每个“汇总攻击”,解析表并确定IDnum行数,并返回所有“汇总攻击”发现的总行数(即攻击)。我想这个数字大约在200.

但是,我正在努力获取 ID 的单独数量,即在IDnum此文本文件的列中。

由于它是一个技术上没有结构的文本文件,我如何解析这个.txt文件,就好像它有一个表格结构来检索IDnum列中的总条目,对于每个Summarized attack遵循上述grep命令的搜索文本?

所需的输出将是上述命令发现的汇总攻击的所有 IDnum 的计数。我不知道计数,但我会想象一个整数输出,类似于80for的返回grep -o -E "Summarized attack: 4"。输出将是<int>由上述 grep 命令找到的所有 80 个“汇总攻击”的列<int>中的行定义的“攻击”数。IDnum

如果另一个命令比其他命令grep更适合,那没关系。

标签: bashparsinggrep

解决方案


  1. 要计算匹配项,您可以使用 grep-c

    grep -cE '(^Summarized.attack:.4[0-9]\.[0-9]+$)'
    
  2. 您可以使用冒号作为分隔符进行剪切-d
    (如果您循环遍历结果,则前导空格不关心)

    grep -oE '(^Summarized.attack:.4[0-9]\.[0-9]+$)' | cut -d: -f2
    

示例循环

   file="path/to/master-listfile-condensed.txt"
   for var in $(grep -oE '(^Summarized.attack:.4[0-9]\.[0-9]+$)' "$file" | cut -d: -f2)
     do
       printf "Summarized attacks: %s: %s\n" $var \
       $(grep -cE "(^.${var}[0-9]+/[0-9]{2}/[0-9]{4})" "$file")
   done

^行首行
$
.任何字节(在本例中为单个空格)
\.单个点(转义)
[0-9]单个数字
+一次(或多次)出现
{4}四次


推荐阅读