![如何使用 grep 查找大文件中的地址?](https://linux22.com/image/7392/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20grep%20%E6%9F%A5%E6%89%BE%E5%A4%A7%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E5%9C%B0%E5%9D%80%EF%BC%9F.png)
我有一个练习要做,其中我收到了一份虚构的电子邮件记录,其中电子邮件的所有者被邀请到某个地方度假。虽然日志很大,所以为了加快速度,我必须grep
以某种方式使用来查找电子邮件地址所有者的标题地址。
地址的基本书写形式为:
name firstName
streetName streetNumber
postalCode(zip) City
现在我知道邮政编码通常为 5 位数字,因此我可以开始查找带有邮政编码的行。到目前为止,我是这样做的:
grep -C2 ^[0-9][0-9][0-9][0-9][0-9] emails
该命令给出了所有以连续 5 位数字开头的行及其周围的两行 ( -C2
)。有了这个,我确实能够找到地址,但仍然有很多不必要的行出现在它周围。我必须指定搜索才能仅获取地址。
所以我尝试搜索以 5 位数字开头并以任何字母结尾的行,如下所示:
grep -C2 ^´[0-9][0-9][0-9][0-9][0-9][A-Z]$´ emails
但最终什么也没找到。这可能是因为它搜索仅包含 5 个字符和一个字母的行。但我不知道如何告诉grep
搜索一行仅搜索一行开始有 5 位数字和 结束用一个字母(或者更好的是一个单词)。
我的下一个最佳尝试是通过搜索仅包含两个单词的行来搜索姓名和名字。但我不知道该怎么做,也找不到任何对此进行解释的讨论。
我希望你们能帮帮我,好吗?
答案1
您可以使用grep -B2 -E '^[0-9]{5} +[a-zA-Z]+$'
尝试仅查找地址块。
一些注意事项:
- 查看
man grep
以了解选项 - 请参阅 grep 手册页的末尾,找到详细解释正则表达式语法的手册页,GNU grep 手册页本身也解释了一点正则表达式
-B
是“比赛前的台词”,可能比-C
-E
用于扩展正则表达式语法- 我给出的正则表达式匹配任何具有五个数字的行(
{5}
接受前面的内容五次),然后至少有一个空格(+
接受前面的内容一次或多次),然后只有字母直到行尾。 - 请注意如何引用 grep 的参数。
`
是非常不同于'
或"
。
如果您尝试查找仅包含一个空格的行,则可以尝试查找仅包含两个单词的行:
grep -E '^[^ ]+ [^ ]+'
如果您想在多行上匹配某些内容,我不确定是否grep
可以做到。您可以尝试这样做,sed
它可以将下一行加载到模式空间中,N
然后与该串联进行匹配(看看man sed
这是否适合您)。 (或者perl
,我认为它可以匹配多行模式,但我不知道如何匹配。)
答案2
所以我尝试搜索以 5 位数字开头并以任何字母结尾的行,如下所示:
^[0-9][0-9][0-9][0-9][0-9][A-Z]$
该模式匹配包含以下内容的行仅有的5 位数字和一个(大写)字母。如果您希望它们之间有更多内容,则需要将其包含在模式中。如果您不关心它们之间的关系,请用于.*
匹配任何字符,无限次。您可能还应该包含小写字母,或用于grep -i
忽略大小写。
^[0-9]\{5\}.*[A-Za-z]$
我的下一个最佳尝试是通过搜索仅包含两个单词的行来搜索姓名和名字。但我不知道该怎么做,也找不到任何对此进行解释的讨论。
您可以匹配包含两个简单单词的行,其模式如下:start、word、gap、word、end:
^[[:alpha:]]\+[[:space:]]\+[[:alpha:]]\+$
然而,尝试将名称与正则表达式匹配有很多陷阱。看https://stackoverflow.com/questions/2385701/regular-expression-for-first-and-last-name。