AWK脚本帮助-逻辑问题
我目前正在编写一个简单的.sh脚本,以分析Exim日志文件中与" o'"匹配的字符串。当前,在查看output.txt时,所有内容(每行606行)上都印有0。我猜我的逻辑是错误的,因为awk不会引发任何错误。
这是我的代码(已针对串联和计数器问题进行更新)。编辑:我已经从dmckee的答案中采用了一些新代码,为了简化起见,我现在正在处理旧代码。
awk '/o'\''/ { line = "> "; for(i = 20; i <= 33; i++) { line = line " " $i; } print line; }' /var/log/exim/main.log > output.txt
有任何想法吗?
编辑:为了清楚起见,我在电子邮件地址中拼写为" o",因为"是电子邮件地址中的非法字符(并且在我们的数据库中,仅以o'前缀名称出现)。
编辑2:根据评论请求,这是一些所需输出的经过清理的示例:
[xxx.xxx.xxx.xxx] kathleen.o'[email protected] <kathleen.o'[email protected]> routing defer (-51): retry time not reached [xxx.xxx.xxx.xxx] julie.o'[email protected] <julie.o'[email protected]> routing defer (-51): retry time not reached [xxx.xxx.xxx.xxx] james.o'[email protected] <james.o'[email protected]> routing defer (-51): retry time not reached [xxx.xxx.xxx.xxx] daniel_o'[email protected] <aniel_o'[email protected]> routing defer (-51): retry time not reached
我在循环中从20开始的原因是,第20个字段之前的所有内容只是标准日志信息,对于我而言,此处不需要。对于该解决方案,我所需要的只是IP以外的所有内容(每个550错误的消息对于在那里使用的每个邮件服务器都是不同的。我正在整理一个常见列表)
解决方案
" +"表示awk中的数字加法。如果要连接,只需将常量和/或者表达式用空格分隔即可。
所以这
line += " " + $i
应该成为
line = line " " $i
编辑:iff exim日志文件(我更喜欢Postfix了:)用一个空格隔开,不是以下更简单的方法:
grep -F o\' /var/log/exim/main.log | cut -d\ -f20-33 >output.txt
?
这里没有真正的grep需求。让awk为我们选择匹配的行(并根据修复连接错误):
awk '/o'\''/ { line = "> "; for(i = 20; i <= 33; i++) { line = line " " $i; } print line; }' /var/log/exim/main.log > output.txt
当然,如果我们在上述提示中这样做,最终将需要进行一些奇怪的转义。它在脚本中更干净...
编辑:在第一遍,我错过了+ =问题...
还要假设我们在上面给出的那行是局部的,因为它只有13个字段(默认情况下,这些字段是用空格分隔的)。
"'"在当地不是非法的。根据RFC2821,第4.1.2节:
Local-part = Dot-string / Quoted-string Dot-string = Atom *("." Atom) Atom = 1*atext
2821还为非本地定义的元素引用了RFC2822,因此:
atext = ALPHA / DIGIT / ; Any character except controls, "!" / "#" / ; SP, and specials. "$" / "%" / ; Used for atoms "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
换句话说,"'"是电子邮件本地部分中完全合法的未加引号的字符。现在,这可能在网站上不合法,但这不是我们所说的。
抱歉,我们没有直接关注主题,但我想纠正主张。
脱离任务,更简单的是:python。
import fileinput for line in fileinput.input(): if "'" in line: fields = line.split(' ') print "> ", ' '.join( fields[20:34] )