寻找正则表达式以从 /etc/passwd 中提取电子邮件地址

Posted

技术标签:

【中文标题】寻找正则表达式以从 /etc/passwd 中提取电子邮件地址【英文标题】:Looking for regex to extract email addresses from /etc/passwd 【发布时间】:2010-09-10 20:27:43 【问题描述】:

我的大多数用户在/etc/passwd 中都有与其个人资料相关联的电子邮件地址。它们始终位于第 5 个字段中,我可以抓取,但它们出现在第 5 个字段中以逗号分隔的列表中的不同位置。

谁能给我一个正则表达式来获取此文件中一行中的电子邮件地址(用逗号分隔)? (我将在 bash 脚本中使用 grep 和 sed)

文件中的示例行:

user1:x:1147:5005:User One,Department,,,email@domain.org:/home/directory:/bin/bash
user2:x:1148:5002:User Two,Department2,email2@gmail.com,:/home/directory:/bin/bash

【问题讨论】:

http://www.regular-expressions.info/email.html 这能回答你的问题吗? How to validate an email address using a regular expression? 【参考方案1】:

怎么样:

,([^@]+@[^,:]+)

组包含电子邮件地址的位置。

[根据地址并不总是以逗号结尾的评论更新]

【讨论】:

该字段有时仅以逗号结尾 因此,在使用 RegEx 之前,请务必在前面加上逗号。 或者将 [^,] 替换为 [^,:] - 我认为这样更简单【参考方案2】:

搜索 @ 符号前后的所有电子邮件有效字符。喜欢:

[-A-z0-9.]+@[-A-z0-9.]+

贪婪匹配应该尽可能地提取所有内容,并且会在逗号或冒号处停止。

不过,请检查电子邮件地址中的有效字符。我遗漏了一些(比如 +)

【讨论】:

可能更容易说明你不想要什么,而不是试图找出什么是有效的。在这种情况下,他不想要逗号(如果这在电子邮件地址中有效,那么我认为他对 RegExpr 不走运)。 [^,]+ 在这种情况下可以。 其实我在里面加了下划线。这就是 ]+@[-A-z0-9 的原因。是斜体。 :) 其实除了'_'还有其他合法的字符。有关详细信息,请参阅 RFC 2821 和 RFC 2822。 您可以将右侧(@ 之后)保留为 [-A-Za-z0-9.]+ ,因为 FQDN 只能合法地包含这些字符。根据 RFC,左侧具有更广泛的法律字符集。【参考方案3】:
[a-z0-9!#$%&'*+/=?^_`|~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`|~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

应该捕获大多数 emials

【讨论】:

【参考方案4】:

实际上,这对于 Awk 来说是一个完美的工作。现在,像大多数人一样,我会在继续之前说“我不是 Awk 专家”...

awk -F : 'print $5' /etc/passwd

会得到第 5 个字段,其中 ':' 是来自 /etc/passwd 的字段分隔符 - 它可能是您想要的第 5 个字段。

awk -F , 'print $1'

将从标准输入中获取第一个字段,其中“,”是他的定界符

awk -F : 'print $5' /etc/passwd | awk -F , 'print $1'

将从您的 /etc/passwd 文件中的第五个冒号分隔字段(包含所有这些杂乱无章的字段!)中获取第一个逗号分隔字段(名称字段)。

调整打印 $1 以获取包含您的电子邮件的字段。

毫无疑问,如果没有 Awk 中的管道,就可以做到这一点。我使用 Awk 来分割事物中的字段,而不是其他。我觉得它令人困惑,这是来自喜欢正则表达式的人......

【讨论】:

这仅在地址始终位于相同的逗号分隔字段中时才有效 - 问题指出,事实并非如此。 这是真的,我见过不同的地方,但没有将其解释为不同的逗号分隔字段,但看看这个例子就清楚了。我的错。【参考方案5】:
sed -r -e "s/^.*[,:]([^,:]+@[^,:]+).*$/\1/g" /etc/passwd

会成功的

【讨论】:

【参考方案6】:

标准的RFC 2822怎么样:

(?:[a-z0-9!#$%&'*+/=?^_`|~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`|~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)3(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

是的。而已。 :)

【讨论】:

...实际上,该 RFC 的完整实现有点...复杂:ex-parrot.com/~pdw/Mail-RFC822-Address.html【参考方案7】:
sed 's/,*:\/.*//;s/^.*://;s/.*,//' /etc/passwd

【讨论】:

以上是关于寻找正则表达式以从 /etc/passwd 中提取电子邮件地址的主要内容,如果未能解决你的问题,请参考以下文章

第6天grep正则表达式 ,vim,shell概念

正则表达式练习

正则表达式练习题

第14章 grepsedawk 正则表达式

正则表达式:grep

文本处理工具正则表达式shell编程基础