Использование grep для поиска всех писем - PullRequest
16 голосов
/ 24 мая 2010

Как правильно построить регулярное выражение для программы "grep" linux, чтобы найти всю электронную почту в, скажем, каталоге / etc? В настоящее время мой сценарий выглядит следующим образом:

grep -srhw "[[:alnum:]]*@[[:alnum:]]*" /etc

Работает нормально - см. Некоторые электронные письма, но когда я изменяю их, чтобы поймать один или несколько символов до и после знака "@" ...

grep -srhw "[[:alnum:]]+@[[:alnum:]]+" /etc

.. вообще перестает работать

Кроме того, он не перехватывает электронные письма формы "Name.LastName@site.com"

Помогите!

Ответы [ 7 ]

20 голосов
/ 24 мая 2010

Вот еще один пример

grep -Eiorh '([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' "$@" * | sort | uniq > emails.txt

Этот вариант работает с доменами 3 уровня.

6 голосов
/ 24 мая 2010

grep требует экранирования большинства специальных символов регулярного выражения, включая +.Вы хотите сделать один из этих двух:

grep -srhw "[[:alnum:]]\+@[[:alnum:]]\+" /etc

egrep -srhw "[[:alnum:]]+@[[:alnum:]]+" /etc
5 голосов
/ 31 января 2012

Я изменил ваше регулярное выражение, добавив пунктуацию (например.-_ И т. Д.), Изменив его на

egrep -ho "[[:graph:]]+@[[:graph:]]+"

Это все еще довольно чисто и соответствует ... ну, почти все с @ в нем, конечно. Также домены 3-го уровня, также адреса с «%» или «+» в них. См. http://www.delorie.com/gnu/docs/grep/grep_8.html для хорошей документации по используемому классу символов.

В моем примере адреса были окружены пробелами, что облегчало сопоставление. Если вы просматриваете журнал почтового сервера, например, вы можете добавить <>, чтобы он совпадал только с адресами:

egrep -ho "<[[:graph:]]+@[[:graph:]]+>"

@ Томас, @glowcoder и @oedo все правы. RFC, который определяет, как может выглядеть адрес электронной почты, довольно интересное чтение. (Я использовал GNU grep 2.9 выше, включен в Ubuntu).

Также ознакомьтесь с приведенной ниже версией zpea, она должна быть менее подходящей для триггера.

3 голосов
/ 07 февраля 2013

Я использовал этот для того, чтобы отфильтровать адрес электронной почты , обозначенный символом 'at' и выделенный пробелами внутри текста:

egrep -o "[^[:space:]]+@[^[:space:]]+" | tr -d "<>"

Конечно, вы можете использовать grep -E вместо egrep (расширенный grep). Обратите внимание, что команда tr используется для удаления типичных разделителей электронной почты.

2 голосов
/ 21 ноября 2014

grep -E -o -r "[A-Za-z0-9][A-Za-z0-9._%+-]+@[A-Za-z0-9][A-Za-z0-9.-]+\.[A-Za-z]{2,6}" /etc

Это адаптировано из ответа, который изначально не был моим, но я нашел его очень полезным.Это отсюда:

http://www.shellhacks.com/en/RegEx-Find-Email-Addresses-in-a-File-using-Grep

Они предлагают:

grep -E -o -r "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" /etc

Но у него есть некоторые ложные срабатывания, как '+ персона ..@ example.com 'или' person @ .. com ', и ограничения на пробелы пропускают такие вещи, как "mailto: person@example.com" (технически не электронное письмо, но оно есть);поэтому я немного подправил его.

(Делайте что хотите с опциями grep, я их не очень хорошо знаю)

0 голосов
/ 25 марта 2015

Просто хотел бы отметить, что небольшое изменение этого варианта отлично подходит для получения упоминаний от таких вещей, как твиты в Твиттере:

grep -Eiorh '(@[[:alnum:]_.-]+)' "$@" * | sort | uniq -c

0 голосов
/ 29 июня 2012

Этот рекурсивный прекрасно работает для меня:

grep -rIhEo "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" /etc/*
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...