我有以下表格中的一些样本数据,需要从中提取电子邮件地址:
from=<user@mail.com> (<-- note that this corresponds to $7)
...
...
目前我正在使用它:
awk '/from=<.*>/ {print $7}' mail.log
但是,这只是找到与正则表达式匹配的字符串。
在打印时,它仍会打印出整个内容(如第一个文本框中所示)。
答案 0 :(得分:4)
您可以使用gsub
删除<
和>
周围的所有内容:
awk '{gsub(/(^[^<]*<|>.*$)/, "", $7)}1' file
这里的关键点是(^[^<]*<|>.*$)
,一个可以分成两个块的正则表达式 - &gt; (A|B)
:
^[^<]*<
从字段开头到<
的所有内容。>.*$
从>
到现场结束的所有内容。$ cat a
1 2 3 4 5 6 from=<user@mail.com> 8
1 2 3 4 5 6 <user@mail.com> 8
$ awk '{gsub(/(^[^<]*<|>.*$)/, "", $7)}1' a
1 2 3 4 5 6 user@mail.com 8
1 2 3 4 5 6 user@mail.com 8
答案 1 :(得分:1)
警告:我被告知常规awk
命令(通常在非Linux系统上找到)不支持此命令:
awk '/from=<([^>]*)>/ { print gensub(/.*from=<([^>]*)>.*/, "\\1", "1");}' mail.log
这是gensub
命令的核心。给定正则表达式,它执行替换(默认情况下,在整行上运行,$0
),并返回修改后的字符串。在这种情况下,替代是“\ 1”,它指的是匹配组。所以我们找到了整条线(中间有一些特殊的东西),然后只返回特殊位。
答案 2 :(得分:1)
如果你使用positive look behind:
,GNU grep可以很好地处理这个问题$ grep -Po '(?<=from=<)[^>]*' file
user@mail.com
这将在from=<
中的>
和file
之间打印任何内容。
答案 3 :(得分:1)
iiSeymour's answer是这种情况下最简单的方法,如果你有 GNU grep(正如他所述)。
您甚至可以使用\K
(将丢弃的所有内容放到该点)来简化它:grep -Po 'from=<\K[^>]*' file
。
对于那些不使用GNU grep(实现不带 -P
的PCRE(Perl兼容正则表达式)支持),你可以使用以下管道,这不是最有效的,但很容易理解:
grep -o 'from=<[^>]*' | cut -d\< -f2
-o
导致grep仅输出输入的匹配部分,在这种情况下包括from=<
。cut
命令在<
(第二个字段(-f2
)之后打印子字符串,基于分隔符<
({{ 1}}),,,只有效地打印电子邮件地址。