首页 > 解决方案 > Python正则表达式解析跨越多行的sudoers日志内容

问题描述

我需要从数百个 sudo.log 文件中提取日期、用户和执行的命令。问题是 sudo 日志条目跨越多行,并且该命令可以有多行。

sudoers 中的条目示例如下:

Aug  7 14:14:43 : user1 : TTY=pts/53 ; PWD=/path2 ;
    USER=root ; COMMAND=/path/to/cmd1
Aug  7 14:14:49 : user2 : TTY=pts/53 ; PWD=/usr/home ;
    USER=root ; COMMAND=./myscript.sh -m name -o SCHEDULER
Aug  7 14:15:14 : user3 : TTY=pts/34 ;
    PWD=/path ; USER=root ;
    COMMAND=/usr/bin/egrep ^[a-z]*
    /filename/toto1234
Aug  7 14:15:37 : user4 : TTY=unknown ; PWD=/opt/nagios ; USER=root ;
    COMMAND=/path/to/less
    /var/opt/otherfile
Aug  7 14:16:04 : user4 : TTY=pts/34 ;
    PWD=/usr/local/bin/script ; USER=root ;
    COMMAND=/usr/bin/egrep ^[a-z]*
    /user/local/sbin/tata

注意到的是 sudoers 的每个条目都以日期开头。后跟一个冒号,然后是用户,然后在另一行执行命令。我想捕获日期、用户和命令..

我认为我应该捕获 COMMAND 之后的所有内容,直到再次找到日期?

我有这个捕获日期和用户名的正则表达式,因为它们往往在同一行但不知道如何捕获命令

这就是我到目前为止所拥有的:

(^\w{3}\s+\d+\s\d+:\d+:\d+)\s?:\s?(\w+?)\s+:.*

我一直在这里测试它:

https://regex101.com/r/qFnv0t/2/

我的想法可能是命令捕获所有内容,直到 group1 再次匹配?或者首先我需要修改日志文件并每行输入一个条目?

感谢您的见解。

标签: regexpython-2.7sudo

解决方案


您可以使用捕获组并首先匹配所有不包含 COMMAND 的行。

然后从 COMMAND 之后匹配,直到以“日期类似”模式开头的第一行。

您不必\w+?使用问号来匹配单词字符非贪婪。

^(\w{3}\s+\d+\s\d+:\d+:\d+)\s?:\s?(\w+)\s+:.*(?:\r?\n(?!.*COMMAND).*)*\r?\n.*?COMMAND=(.*(?:\r?\n(?!\w{3}\s+\d+\s\d+).*)*)

关于图案

  • ^字符串的开始
  • (捕获组 1
    • \w{3}\s+\d+\s\d+:\d+:\d+匹配日期格式
  • )关闭组 1
  • \s?:\s?:由可选的空白字符包围的匹配
  • (捕获组 2
    • \w+匹配 1+ 个单词字符
  • )关闭组 2
  • \s+:.*匹配 1+ 个空白字符:和 0+ 次除换行符以外的任何字符
  • (?:非捕获组
  • \r?\n(?!.*COMMAND).*匹配换行符,断言该行不包含 COMMAND。然后匹配 0+ 次除换行符以外的任何字符
  • )*关闭组并重复 0+ 次
  • \r?\n.*?COMMAND=匹配换行符直到第一次出现COMMAND=
  • (捕获组 3
    • .*匹配除换行符以外的任何字符 0+ 次
    • (?:非捕获组
      • \r?\n(?!\w{3}\s+\d+\s\d+).*匹配换行符,断言该行不以类似日期的模式开头,然后匹配该行的其余部分
    • )*关闭非捕获组并重复 0+ 次,因为该命令可以跨越多行
  • )关闭第 3 组

正则表达式演示| Python 示例

请注意,类日期格式不会验证日期本身。


推荐阅读