首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用grep解析非结构化文本文件

用grep解析非结构化文本文件
EN

Stack Overflow用户
提问于 2020-06-20 21:47:11
回答 3查看 189关注 0票数 0

我正在尝试分析来自麻省理工学院,在这里发现的的这个IDS日志文件。

代码语言:javascript
复制
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附近。

但是,我很难获得in的单个数量,即这个文本文件的IDnum列中的in数。

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

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

如果grep以外的另一个命令更适合使用,那就好了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-21 19:35:11

假设您在输入文件中有不止一个“汇总攻击”:这可能是您要寻找的:

代码语言:javascript
复制
$ cat tst.awk
/^Summarized attack:/ {
    prt()
    atk = ($3 ~ /^4/ ? $3 : 0)
    cnt = 0
}
atk { cnt++ }
END {
    prt()
    print "TOTAL", tot
}

function prt() {
    if ( atk ) {
        cnt -= 2
        print atk, cnt
    }
    tot += cnt
}

代码语言:javascript
复制
$ awk -f tst.awk file
票数 1
EN

Stack Overflow用户

发布于 2020-06-21 00:43:20

  1. 要计数匹配,可以使用grep -c。 grep -cE‘(^Summarized.攻击者:.40-9.0-9+$)’
  2. 可以使用冒号作为裁剪-d的分隔符。 (如果循环执行结果,前导空格不关心) grep -oE '(^Summarized.attack:.40-9.0-9+$)‘\x{e76f}\x{e76f}’-d:-f2

示例循环

代码语言:javascript
复制
   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}四发生

票数 2
EN

Stack Overflow用户

发布于 2020-06-21 02:00:25

对于第一部分,fgrep -c "Summarized attacks: 4"fgrep -F "Summarized attacks: 4"就足够了。

如果我理解您的第二部分,对于其中的每一个块,您希望将攻击行相加,并打印一个总计。你可以用

代码语言:javascript
复制
gawk '/^Summarized attack: 4/ { on=1; next} /^ 4[0-9.]*/ { if (on) ++ids; next} /^ IDnum/ {next} /^ */ {next} { on=0} END {print ids;}'< master-listfile-condensed.txt

第一条语句说,搜索(/.../)中以(^)“概括攻击: 4”开头的每一行,在找到它后,打开" on“标志,然后转到下一行。第二条语句说,如果这是一个攻击记录(即以4开头,后面跟着数字的字符串* ),那么检查标志;如果是,计数它。基本上,当我们在目标攻击记录的一节中时,我们希望旗子是亮的。后面的两个语句表示,对于以“IDnum”开头的每一行或所有空格(有时插入空行),转到下一行;这是抵消下一条语句的需要,该语句指出,如果这不是与前面任何语句匹配的行,则关闭"on“标志。这使我们无法计算目标以外的攻击。最后,END的意思是在结尾,打印总计。我得到了757,它离你的范围很远。但我认为这是正确的。

但是,假设总结的时间戳总是在IDnum中重复至少在第一个重要数字中重复,一个更简单的方法是使用

代码语言:javascript
复制
grep -Ec '^ 4' master-listfile-condensed.txt

这意味着计算以空格-4开头的所有行。在这种情况下,它给出了正确的结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62492088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档