使用正则表达式重新格式化日志文件
Logfile reformatting with regex
我正在使用 grep 过滤日志文件中的某些行,并将它们呈现给我的 conky 配置。
日志文件是 /var/log/messages。
这些条目与 UFW 块事件有关。
问题是我只关心每一行的某些字符串。
我可以 grep 唯一的 UFW 块,但是该行太长而无法放入 conky。
即使 conky 不是等式的一部分,学会只显示日志行的片段对我将来也有好处。
我通过以下方法取得了成功:
grep -Ewoh '(IN=([a-z]){4,})|((DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3})|(PROTO=[a-z]{2,6})|((SPT|DPT)=[0-9]{1,5})' /var/log/messages
这个丑陋的正则表达式正在过滤条目(例如):
IN=wlan0
SRC=10.10.123.23
DST=192.168.41.23
PROTO=TCP
SPT=443
DPT=41080
哪(几乎)一行是这样的:
'
IN=([a-z]){4,}
(DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3}
PROTO=[a-z]{2,6}
(SPT|DPT)=[0-9]{1,5}
'
问题在于,这会为每个匹配的单词生成一个新行,我只需要每行的过滤字符串,在它们的行中。
$ grep -Ewoh '(IN=([a-z]){4,})|((DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3})|(PROTO=[a-z]{2,6})|((SPT|DPT)=[0-9]{1,5})' /var/log/messages
IN=wlan
SRC=103.81.76.20
DST=172.31.77.54
SPT=443
DPT=41080
$
我宁愿不使用非常复杂的 awk 方法,除非我可以在几个月后回到它并轻松记住它。 awk 是不可思议的,但如果你丢球一次就很难消化!
谢谢。
如果我理解正确,而不是 grep -o
提供的列表,您想要删除不匹配的字符串,并只打印匹配的字符串。 IE。在它们出现的行和顺序中。
使用 gawk
的 FPAT
:
gawk -v FPAT='my-regex' '='
- 将
my-regex
替换为您要查看的字符串的正则表达式。
- 这将按顺序在每一行上打印匹配项,由 space.
分隔
- 添加
-v OFS=
以删除 space,或者例如 -v OFS=', '
以更改定界字符串。
- 您正在使用
grep -w
来匹配整个单词。您可以在 gawk 正则表达式中通过使用 \<
和 \>
左右单词边界(分别)来执行此操作。
- 例如,在 'or' 个运算符 (
|
) 的整个列表周围添加括号和单词边界:
-v FPAT='\<((IN=([a-z]){4,})|((DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3})|(PROTO=[a-z]{2,6})|((SPT|DPT)=[0-9]{1,5}))\>'
- 请注意正则表达式中的错误,例如 tshiono 评论的错误,它不会匹配
PROTO=TCP
。
我正在使用 grep 过滤日志文件中的某些行,并将它们呈现给我的 conky 配置。 日志文件是 /var/log/messages。 这些条目与 UFW 块事件有关。
问题是我只关心每一行的某些字符串。 我可以 grep 唯一的 UFW 块,但是该行太长而无法放入 conky。 即使 conky 不是等式的一部分,学会只显示日志行的片段对我将来也有好处。
我通过以下方法取得了成功:
grep -Ewoh '(IN=([a-z]){4,})|((DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3})|(PROTO=[a-z]{2,6})|((SPT|DPT)=[0-9]{1,5})' /var/log/messages
这个丑陋的正则表达式正在过滤条目(例如):
IN=wlan0
SRC=10.10.123.23
DST=192.168.41.23
PROTO=TCP
SPT=443
DPT=41080
哪(几乎)一行是这样的:
'
IN=([a-z]){4,}
(DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3}
PROTO=[a-z]{2,6}
(SPT|DPT)=[0-9]{1,5}
'
问题在于,这会为每个匹配的单词生成一个新行,我只需要每行的过滤字符串,在它们的行中。
$ grep -Ewoh '(IN=([a-z]){4,})|((DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3})|(PROTO=[a-z]{2,6})|((SPT|DPT)=[0-9]{1,5})' /var/log/messages
IN=wlan
SRC=103.81.76.20
DST=172.31.77.54
SPT=443
DPT=41080
$
我宁愿不使用非常复杂的 awk 方法,除非我可以在几个月后回到它并轻松记住它。 awk 是不可思议的,但如果你丢球一次就很难消化!
谢谢。
如果我理解正确,而不是 grep -o
提供的列表,您想要删除不匹配的字符串,并只打印匹配的字符串。 IE。在它们出现的行和顺序中。
使用 gawk
的 FPAT
:
gawk -v FPAT='my-regex' '='
- 将
my-regex
替换为您要查看的字符串的正则表达式。 - 这将按顺序在每一行上打印匹配项,由 space. 分隔
- 添加
-v OFS=
以删除 space,或者例如-v OFS=', '
以更改定界字符串。 - 您正在使用
grep -w
来匹配整个单词。您可以在 gawk 正则表达式中通过使用\<
和\>
左右单词边界(分别)来执行此操作。 - 例如,在 'or' 个运算符 (
|
) 的整个列表周围添加括号和单词边界: -v FPAT='\<((IN=([a-z]){4,})|((DST|SRC)=(([0-9]){1,3}\.){3,}([0-9]){1,3})|(PROTO=[a-z]{2,6})|((SPT|DPT)=[0-9]{1,5}))\>'
- 请注意正则表达式中的错误,例如 tshiono 评论的错误,它不会匹配
PROTO=TCP
。