<
我在和字符之间有一个很长的电子邮件列表>
:
smeimebv2t <jdyefc@nsuwtcvc>; jdedyvt <ejd2ydt2@dv2dg2vgv>; didi2jd2m <i2dmi32@hd2vdg >; 3idm23i2m <2udhu2@cdrrc>
.
.
.
如何使用 awk 或 perl oneliner 来仅捕获 之间的电子邮件地址< >
?
例子:
more results.out
jdyefc@nsuwtcvc
ejd2ydt2@dv2dg2vgv
i2dmi32@hd2vdg
2udhu2@cdrrc
答案1
我能想到的最简单的方法是使用 GNU grep
:
$ grep -Po '<\K[^>]+(?=>)' file
jdyefc@nsuwtcvc
ejd2ydt2@dv2dg2vgv
i2dmi32@hd2vdg
2udhu2@cdrrc
这-o
意味着“仅打印该行的匹配区域”并-P
激活 Perl 兼容正则表达式。这些让我们使用\K
这意味着“不要将到目前为止匹配的任何内容视为匹配的一部分”并且积极的前瞻。因此,正则表达式将匹配<
,然后匹配任何非>
字符,后跟>
。
请注意,这也将匹配<foo>
非电子邮件。要仅限于电子邮件(带有 的字符串@
),您可以使用:
grep -Po '<\K[^>]+@[^>]+(?=>)' file
答案2
perl -lne 'print for /<\K[^>]+/g'
答案3
使用呆呆:
awk -v RS="[<>]" '/@/'
答案4
另一种变体:
perl -lne 'print $1 while /<(.*?)>/g'
括号捕获到$1
,.*?
使匹配变得非贪婪,即尽快停止。
和awk
:
awk -F'<' '{ for(i = 2 ; i <= NF ; i++) { sub(/>.*/, "", $i); print $i; } } '
<
在s上拆分行,忽略第一部分,删除以 开头的任何内容后打印其他部分>
。如果>
a 之后没有,这将打印该行的其余部分<
。