如何将unicode字符与awk的正则表达式正确匹配?

时间:2014-10-20 14:11:18

标签: regex shell unicode awk

我在脚本中有以下语句,要从各种电子邮件日志中检索电子邮件地址的域部分,并使用可靠格式的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字符不匹配。匹配这样一行的正确的正则表达式语句是什么?

2 个答案:

答案 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 以及什么不是