我想将grep与-f,-i和-v选项一起使用。我有一个包含以下内容的模式文件:
的vchkpw-POP3
用vchkpw提交
USER_UNKNOWN
unknown_user
address_rejected
no_such_user
does_not_exist
invalid_recipient
mailbox_unavailable
user_not_found
no_mailbox_here
我希望在处理qmail邮件日志文件时排除上述所有条款。
使用Grep 2.5.1,它似乎不适用于从第3个位置开始的任何模式。
我正在使用一行bash代码来解析我的maillog文件。见下面的一行:
cat /var/log/maillog | tai64n2tai | awk '{$1="";$2="";$3="";$4="";$5="";print}'
| grep -v vchkpw-pop3 | grep -v vchkpw-submission | awk '{sub(/^[ \t]+/,"")};1'
| qlogselect start $STARTDAY end $ENDDAY | matchup > $QMAILSTATS 5>/dev/null
而不是在管道中使用多个grep -v“sometext”,我想在它们的位置使用grep -vif patterns.txt。
但是,我的问题是,在我的grep版本中,如果模式中包含下划线(_),它将不允许我一起使用f和i选项。如果我删除下划线,则模式会按预期匹配。
以下是我在解析maillog时要省略的示例行:
Sep 20 15:46:50 m qmail: 1348123610.323831 delivery 11150428: failure: 204.119.19.51_does_not_like_recipient./Remote_host_said:_550_5.1.1_User_unknown/Giving_up_on_204.119.19.51./
由于错误消息取决于我正在联系的邮件服务器,因此有时模式user_unknown具有大写字母,有时则不是。
任何人都有更好的解决方案吗?
我喜欢不必每次都编辑一行bash命令,只需添加/删除文件中的模式。
答案 0 :(得分:0)
这是使用GNU awk
的一种方式,假设您将模式保存在名为patterns.txt
的文件中。这是script.awk
:
BEGIN {
IGNORECASE=1
}
FNR==NR {
patterns[$0]++
counter++
next
}
{
$1=$2=$3=$4=$5=""
sub(/^[ \t]+/,"")
for (i in patterns) {
if ($0 !~ i) {
count++
}
}
if (counter == count \
&& !/^$/) {
print
}
count = 0
}
像这样跑:
< /var/log/maillog | tai64n2tai | awk -f script.awk patterns.txt - | qlogselect start $STARTDAY end $ENDDAY | matchup > $QMAILSTATS 5>/dev/null
或者,如果您不想使用脚本,您会发现这个内容很有用:
< /var/log/maillog | tai64n2tai | awk 'BEGIN { IGNORECASE=1 } FNR==NR { patterns[$0]++; counter++; next } { $1=$2=$3=$4=$5=""; sub(/^[ \t]+/,""); for (i in patterns) { if ($0 !~ i) { count++ } } if (counter == count && !/^$/) { print } count = 0 }' patterns.txt - | qlogselect start $STARTDAY end $ENDDAY | matchup > $QMAILSTATS 5>/dev/null