使用 grep 和 awk 过滤日期

使用 grep 和 awk 过滤日期

.bash_aliases我在我的文件中创建了下面的别名

alias auth="grep \"$(date|awk '{print $2,$3}')\" /var/log/auth.log |
            grep -E '(BREAK-IN|Invalid user|Failed|refused|su|Illegal)'"

这应该是:

  • 检查今天的日期
  • grepauth.log获取今天的消息
  • grep Todays messages 用于匹配特定字符串的警告消息

但是,它仅在日期为 2 位数时才有效,因为编号 <10 的天数前面没有零。

例如,我运行date并将结果通过管道传输到awk.date输出Sat Jan 1 04:56:10 GMT 2011,然后 awk 捕获$2并将$3它们输入到 grep 中,如下所示

Jan 1

但是,当有一位数的日期时,消息将auth.log显示如下

Jan  1 00:44:57 linux su[21249]: pam_unix(su:session): session closed for user root

Jan因此,后面有两个空格,但在我的 grep 命令中auth.log只有一个空格Jan

如何修改命令以留出额外的空间?

答案1

date | awk ...您可以将格式说明符与 date 命令一起使用以获得所需的格式,而不是使用。根据date(1)手册页,%b是月份名称的缩写,%e是月份中的第几天,空格填充,与 相同%_d

以下日期命令应该为您提供所需格式的字符串:

date "+%b %e"

您还可以将其他字符放入格式说明符中,因此如果您使用:

date "+^%b %e"

您将得到一个仅与行开头的日期匹配的 grep 模式。这将防止日志消息部分中存在日期的任何错误匹配。

正如 Steven D 所指出的,您还可以通过一次调用来完成此操作grep

auth()
{
    grep -E "$(date '+^%b %e')"'.*(BREAK-IN|Invalid|user|Failed|refused|su|Illegal)' /var/log/auth.log
}

我根据与引用相关的评论中提到的问题做了一些更改。我的引用规则是在将单独的单词分组为单个单词时使用单引号,并防止元字符的 shell 扩展,并且仅当您想要在多单词字符串内扩展时才使用双引号。

原始答案的date格式字符串用双引号引起来,根据我的上述规则,这是错误的。我现在已经改变了这一点。编辑将 grep 字符串放入双引号中。我将其放回到单引号中,因为 shell 元字符和 grep 正则表达式 (RE) 元字符之间经常存在重叠,您几乎总是希望将 RE 单引号引用到 grep。当前字符串可能不需要单引号,但如果此 shell 函数随着时间的推移而演变,它可能会因未来的更改而中断。

因为问题是询问要放入别名中的命令,所以本答案中未显示额外的引用级别。使用 shell 函数而不是别名会更简单,因此您不需要处理这种额外的引用。嵌套引用很快就会变得混乱,因此您应该采取一切措施来避免这种情况。

我已经将其作为 shell 函数进行了测试,使用 Gilles 建议来模糊日期,它“对我有用”。

相关内容