我正在使用以下命令查找登录电子邮件服务器的结果日志条目:
egrep '_login[^ ]' /var/log/exim_mainlog
这可以很好地找到包含如下内容的条目:
P=esmtpa A=courier_login:[email protected] S=1573 id=f1cd08396,...
但我需要做的是改变我的 grep 语句,以便它找到不使用 @ 符号的单词登录,如下所示:
P=esmtpa A=courier_login:name S=1573 id=f1cd08396,...
之前的登录信息是“[电子邮件保护]“,但在第二条日志条目中,使用的日志只有“名称”。
是否可以使用 grep 或 egrep 来实现这一点,也许是在某种复合语句中?
非常感谢。
答案1
扩展的正则表达式_login[^ ][^@]+\s
应该可以做到这一点。
即文字字符串_login
后跟一个非空格字符,后跟至少一个非字符@
,后跟一个空格字符。
答案2
如果您只想提取不包含@字符的登录名,以下sed
命令可能会派上用场:
echo -e "P=esmtpa A=courier_login:[email protected] S=1573 id=f1cd08396,...\nP=esmtpa A=courier_login:name2 S=1573 id=f1cd08396,..." | \
sed -nr 's/^.*_login:([^ @]+) .*$/\1/p'
运行此脚本将产生以下输出:
name2
一些解释:
第一行仅回显了两行示例数据(以换行符分隔
\n
)。第二行包含
sed -nr
命令,在本例中它使用s/regexp/replacement/p
语法。它(s
)在行中搜索匹配的regexp
正则表达式(-r
)。如果行的一部分匹配,将replacement
使用替换匹配部分。-n
开关和p
命令只需要省略不匹配的行regexp
。sed
_login:
在一行中定位字符串“ ”。在该位置:- 左括号标记子表达式的开始。(将其视为行的一个区域。)
- 匹配
[^ @]+
一个既不是空格也不是 @ 的字符。它将一直扩展,直到找到空格字符。 - 结束括号标记了该字符之前的子表达式的结束。匹配的区域存储在名为的变量中
\1
。
- 如果你看一下该
regexp
部分,它基本上遵循了以下^.*something.*$
模式。^.*
匹配行首的任何字符,直到表达式某物. 类似地,.*$
匹配表达式后面行尾的任何字符某物。将整行与 匹配regexp
非常重要,因为整个匹配的部分都会被替换。 - 替换部分仅包含
\1
变量,因此将替换匹配的登录名。