在"<"之间打印文本和">"在awk

时间:2015-03-03 11:12:03

标签: regex linux shell awk

我有以下表格中的一些样本数据,需要从中提取电子邮件地址:

from=<user@mail.com> (<-- note that this corresponds to $7)
...
...

目前我正在使用它:

awk '/from=<.*>/ {print $7}' mail.log

但是,这只是找到与正则表达式匹配的字符串。

在打印时,它仍会打印出整个内容(如第一个文本框中所示)。

4 个答案:

答案 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}}),,,只有效地打印电子邮件地址。