0

在以下情况下如何使用 AWK?

示例输入:

17  mary@mysite.co.uk
9   Limited <office@domain.com>
8  "Fishing Forum" <dra.78@gmail.com>

期望的输出:

17  mary@mysite.co.uk
9   office@domain.com
8   dra.78@gmail.com

我想用每行的电子邮件地址打印 $1。

4

4 回答 4

2

为了处理所有可能的电子邮件选项(请参阅三重注释),您需要将电子邮件与正则表达式匹配:

gawk --re-interval '{match($0,/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,4}/);print $1 " " substr($0,RSTART,RLENGTH)}'

它取自这里的正则表达式:http ://www.regular-expressions.info/email.html 。您应该对其进行测试以验证它是否涵盖所有合法电子邮件。

于 2013-01-14T10:15:52.610 回答
1

如果你的数据真的像你展示的那样简单,你可以使用 awksub()函数来解决你不想要的东西,即

 awk '{
      # inside the implied awk process-all-lines-of-input-loop
      email=$0
      if (email ~ /<\.*>/) {
        sub(/^.*</,"", email)
        sub(/>.*$/,"", email)
      } 
      else { email=$2 }
      printf("%s\t%s\n", $1, email)
      }' mailFile > newMailFile

cat newMailFile
17      17  mary@mysite.co.uk
9       office@domain.com
8       dra.78@gmail.com

请注意,我们已将完整的行 ( $0) 复制到变量email中,然后删除了从左侧开始的所有字符,直到第一个字符,然后删除了从结束字符开始的变量<末尾的任何内容。请注意,对于极端情况,电子邮件地址的解析可能相当复杂,因此这种技术可能会遗漏某些情况,但鉴于它的简单性,它应该已经足够好了。email>

此外,如果您不习惯 awk 和 shell 编程,请注意,您不能使用相同的输出文件名覆盖输入文件“不要尝试类似awk '....' file > file. 它基本上会清除 file.

printf 是一种打印数据的奇特方式,\t它在两个字段之间为您提供了一个制表符字符。你也可以更简单地使用print $1 "\t" email.

IHTH。

于 2013-01-14T02:30:39.640 回答
0
$ cat stack 
17  mary@mysite.co.uk
9   Limited <office@domain.com>
8  "Fishing Forum" <dra.78@gmail.com>

$ cat stack | awk '{ print $1" "$NF }' | sed 's/<//g; s/>//g'
17 mary@mysite.co.uk
9 office@domain.com
8 dra.78@gmail.com

如果您想要tab输出的第一列之间,请使用如下:

$ cat stack | awk '{ print $1"\t"$NF }' | sed 's/<//g; s/>//g'
17  mary@mysite.co.uk
9   office@domain.com
8   dra.78@gmail.com

如果您只需要电子邮件地址:

$ cat stack | awk '{ print $NF }' | sed 's/<//g; s/>//g'
mary@mysite.co.uk
office@domain.com
dra.78@gmail.com

仅供参考: NF为您提供一行中的字段总数

于 2013-01-14T03:41:32.477 回答
0

您可以为此使用“sed”

$ ./test.sh | sed -r -e 's/<//g' -e 's/>//g' -e 's/^([0-9]+).* (.+)$/\1 \2/'
17 mary@mysite.co.uk
9 office@domain.com
8 dra.78@gmail.com
于 2013-01-14T11:41:26.970 回答