我在脚本中有以下语句,要从各种电子邮件日志中检索电子邮件地址的域部分,并使用可靠格式的To:行:
awk '/^To: / { r = gensub(/^To: .+@(.+) .*$/, "\\1", "g"); print r}'
这匹配To: doc@bequerelint.net (Omer)
等行。但是,它与行To: andy.vitrella@uol.com.br (André)
或To: boggers@operamail.com (Pål)
不匹配,也不在电子邮件地址后面的尾随括号中包含非ascii字符的任何其他行。
顺便提一下,第一个非匹配示例的od -c
给出:
0000000 T o : a n d y . v i t r e l l
0000020 a @ u o l . c o m . b r ( A n
0000040 d r 351 ) \n
0000045
我猜测awk的正则表达式.
与(André)
中的非ascii字符不匹配。匹配这样一行的正确的正则表达式语句是什么?
答案 0 :(得分:2)
我将我的评论作为答案,让代码格式正确,
% echo 'To: andy.vitrella@uol.com.br (André)
To: boggers@operamail.com (Pål)' | gawk '/^To: / { r = gensub(/^To: .+@(.+) .*$/, "\\1", "g"); print r}'
uol.com.br
operamail.com
% echo 'To: andy.vitrella@uol.com.br (André)
To: boggers@operamail.com (Pål)' > fileee12
% gawk '/^To: / { r = gensub(/^To: .+@(.+) .*$/, "\\1", "g"); print r}' fileee12
uol.com.br
operamail.com
% env | grep -e '\(LOC\)\|\(LAN\)'
LANG=C
XTERM_LOCALE=C
%
如您所见,您的命令既可以从stdin读取也可以使用C语言环境从文件中读取,因此我可以排除计算机上的 它是区域设置或读取之间的差异stdin而不是从文件中产生影响。
我的电脑有linux,我的gawk是4.1.1,你的情况如何?
答案 1 :(得分:1)
进一步简化它,其中区域设置根本不重要
{mawk/mawk2/gawk [-b]? -e} 'BEGIN { FS = "\100"; # ampersand
} /^To: / && ( NF > 1 ) { # play it safe in case
# of no ampersand
print ($2 !~ / /) ? $2 : \ # in case no "(Omer)" towards the end
\
substr($2, 1, index($2, " ") - 1);
}'
由于电子邮件地址中的空格无效(除非是 URI 编码的 (?)),并且您必须用 @ 进行强制分隔,因此单独使用这个 substr 就可以完成它,而没有所有 gsub 和 unicode 以及什么不是