Python 用于解析跨越多行的 sudoers 日志内容的正则表达式
Python regex to parse contents of sudoers log that spans accross multiple lines
我需要从数百个 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 再次匹配?或者首先我需要修改日志文件并每行输入一个条目?
感谢您的见解。
您可以使用捕获组并首先匹配所有不包含 COMMAND 的行。
然后从 COMMAND 之后匹配到以 "date like" 模式开头的第一行。
您不必使用问号使匹配单词字符非贪婪\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
请注意,类日期格式本身不会验证日期。
我需要从数百个 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 再次匹配?或者首先我需要修改日志文件并每行输入一个条目?
感谢您的见解。
您可以使用捕获组并首先匹配所有不包含 COMMAND 的行。
然后从 COMMAND 之后匹配到以 "date like" 模式开头的第一行。
您不必使用问号使匹配单词字符非贪婪\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
请注意,类日期格式本身不会验证日期。