Ответ 1
Вот еще один пример
grep -Eiorh '([[:alnum:]_.-][email protected][[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' "[email protected]" * | sort | uniq > emails.txt
Этот вариант работает с доменами 3 уровня.
Как правильно построить регулярное выражение для программы "grep" linux, чтобы найти все сообщения электронной почты, скажем каталог /etc? В настоящее время мой script выглядит следующим образом:
grep -srhw "[[:alnum:]]*@[[:alnum:]]*" /etc
Он работает нормально - см. некоторые из писем, но когда я его изменяю, чтобы поймать один или несколько символов раньше и после знака "@"...
grep -srhw "[[:alnum:]][email protected][[:alnum:]]+" /etc
.. он вообще перестает работать
Кроме того, он не ловит электронные письма формы "[email protected]"
Справка!
Вот еще один пример
grep -Eiorh '([[:alnum:]_.-][email protected][[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' "[email protected]" * | sort | uniq > emails.txt
Этот вариант работает с доменами 3 уровня.
grep
требуется большая часть специальных символов регулярного выражения для экранирования - включая +
. Вы хотите сделать одно из этих двух:
grep -srhw "[[:alnum:]]\[email protected][[:alnum:]]\+" /etc
egrep -srhw "[[:alnum:]][email protected][[:alnum:]]+" /etc
Я изменил ваше регулярное выражение, чтобы включить пунктуацию (например.-_ и т.д.), изменив ее на
egrep -ho "[[:graph:]][email protected][[:graph:]]+"
Это все еще довольно чисто и соответствует... ну, и все, что угодно с @в нем, конечно. Также домены третьего уровня также обращаются к "%" или "+" в них. См. http://www.delorie.com/gnu/docs/grep/grep_8.html для хорошей документации по используемому классу символов.
В моем примере адреса были окружены белым пространством, что упрощало сопоставление. Если вы, например, grep через журнал почтового сервера, можете добавить < > чтобы он соответствовал только адресам:
egrep -ho "<[[:graph:]][email protected][[:graph:]]+>"
@thomas, @glowcoder и @oedo все правы. RFC, который определяет, как адрес электронной почты может выглядеть, довольно забавно. (Я использовал GNU grep 2.9 выше, включенный в Ubuntu).
Также ознакомьтесь с версией zpea ниже, она должна сделать для менее согласованного с триггером совпадения.
Я использовал это для фильтрации адреса электронной почты , идентифицированного символом 'at', и выделенного пробелами в тексте:
egrep -o "[^[:space:]][email protected][^[:space:]]+" | tr -d "<>"
Конечно, вы можете использовать grep -E вместо egrep (расширенный grep). Обратите внимание, что команда tr используется для удаления типичных разделителей электронной почты.
grep -E -o -r "[A-Za-z0-9][A-Za-z0-9._%+-][email protected][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._%+-][email protected][A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" /etc
Но у него есть определенные ложные срабатывания, такие как "+ person.. @example.com" или "person @.. com", а ограничения пробелов пропускают такие вещи, как "mailto: [email protected]" (не технически электронная почта, но содержит один); поэтому я немного изменил его.
(Делайте то, что хотите, с параметрами grep, я их не очень хорошо знаю)
Эта рекурсивная работа отлично подходит для меня:
grep -rIhEo "\b[a-zA-Z0-9.-][email protected][a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" /etc/*
Просто хотел упомянуть, что небольшая вариация этого отлично подходит для захвата упоминаний о вещах вроде twitter tweets:
grep -Eiorh '(@[[:alnum:]_.-]+)' "[email protected]" * | sort | uniq -c