我正在编写一个 shell 脚本,用于将 fail2ban 日志发送到 postgres 数据库。应用程序日志中的事件时间戳令人讨厌地显示以逗号分隔的事件毫秒数(例如:11:01:26,899),postgres 不喜欢这样,我也不需要,以下是日志中的一行示例:
2023-02-09 11:01:26,899 fail2ban.filter [6823]: INFO [sshd] Found xxx.xxx.xxx.xxx - 2023-02-09 11:01:26
这是文件中唯一有逗号的地方。是否可以使用 sed 删除此逗号和接下来的 3 个字符?
答案1
以下命令删除由逗号和逗号后三个字符组成的子字符串:
sed 's/,...//' input.log
注释和说明:
从技术上讲,该
s
命令执行的是替换。我们通过用空字符串替换某些内容来删除它们。在我们的代码中,相关的空字符串位于第二个和第三个斜杠之间。在正则表达式中
,
是文字,.
匹配任何字符。我将表达式放在单引号内。在这种情况下,这种引用是不必要的,但一般来说,
sed
代码中经常包含会被 shell 解释的字符(我们不希望出现这种情况),因此习惯使用引用是很好的。我们的命令对每行输入最多进行一次替换。在一行中,只有第一个匹配的子字符串会被替换。
,...
是一个简单的模式。如果每行都以给定格式的时间戳开头,则不需要复杂的模式或逻辑。
答案2
给定文件input.log
,以下sed
命令将从时间戳中删除毫秒部分:
sed -r 's/([0-9]{2}:[0-9]{2}:[0-9]{2})(,[0-9]{3})/\1/' input.log
这将用第一个捕获组替换上面的两个捕获组(捕获组一是时间%H:%M:%S
,捕获组二是逗号和毫秒)。,%3N
然后可以将其重定向到另一个文件:
sed -r 's/([0-9]{2}:[0-9]{2}:[0-9]{2})(,[0-9]{3})/\1/' input.log > output.log
output.log
输出文件在哪里。
更新:删除了不必要的g
标志。请参阅@kamil-maciorowski 的答案,以获得更简单、更简洁的解决方案。