2013-07-23 2 views
2

Я пытаюсь ознакомятся с sed извлекая адреса электронной почты от входа в следующем виде:Использование СЭД для извлечения адреса электронной почты

something_from.someone:[email protected]

То есть вход Я посылаю к sed, Я стараюсь, чтобы удалить все, вплоть до и включая ::

sed 'd/[[alphanum:]]+[.][[:alphanum:]]+[:]//' 

на основании своих исследований, это должно сделать это, но я получаю эту ошибку:

sed: 1: "d/[[:alphanum:]]+[.][[: ...": extra characters at the end of d command

Любые идеи относительно того, что я делаю неправильно?

+0

Использование регулярных выражений, вероятно, лучший способ. Это регулярное выражение соответствует 99,99% адреса электронной почты: /^ (([^ <>() [\] \\.,;: \ S @ \ "] + (\. [^ <>() [\] \ \,;:... \ s @ \ "] +) *) | (\" + \ ")) @ ((\ [[0-9] {1,3} \ [0-9] {1, 3} \ [0-9] {1,3} \ [0-9] {1,3} \]) |.. (. ([A-Za-Z \ -0-9] + \) + [ a-zA-Z] {2,})) $/ – Alban

+0

@ Албан Спасибо! Но мой вопрос не в том, что касается адреса электронной почты. Я пытаюсь понять, как использовать 'sed', а также понять, почему моя команда выше не работает. –

+1

Это делает это в sed: 'sed 's /.*: \ (. \)/\ 1/g''. У меня недостаточно знаний языка, чтобы указать, что плохого в вашем коде. – fedorqui

ответ

3

Синтаксис удаления неверен. Чтобы удалить в СЭД вам нужно сделать:

sed '(separator) [pattern to delete](separator)d' 

Так, например:

sed -e '/regex/d' infile 

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

sed -e 's/regex-to-drop\(regex-to-keep\)/\1/g' input-file 

«s» для замены и «г» является для глобальных и \(\) является что захвачено, а \1 - это то место, где я хочу захватить вещь. Если бы я имел ряд захваченных пунктов,

\(something\)\(something_else\) 

Я мог бы воспроизвести их с другим характером между ними, просто помещая следующее в замещающей части SED команды:

\1 ;; \2 

Это будет производить: something ;; something_else и вообще будет выглядеть так:

sed -e 's/\(something\)\(something_else\)/\1 ;; \2/g' input-file 

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

sed -e 's/^.*:\(.*\)$/\1/g' input-file 

Сноска к вышесказанному как это было предложено @fedorqui:

Сед использует стандартные регулярки обозначение для обозначения начала и конца строки, так что «^» относится к началу строки и «$» относится к концу строки. Таким образом, полное объяснение выше выглядит следующим образом:

's/^.*: 

Все от начала линии до двоеточия («S» означает, что мы устанавливаем команду «замените»).

Тогда:

\(.*\)$/ 

CAPTURE все до конца строки, и

/\1/g' 

Заменитель ЦЕЛЫЙ линия с захваченного пункта. Сделайте это глобально (для всего файла).

+0

Можете ли вы использовать '[[: alphanum:]]' и т. Д. В 'sed' ? –

+1

Да, но это выглядит как '[: alpha:]', '[: alnum:]' и '[: digit:]'. – erewok

+0

Это потрясающее объяснение, поздравляю. Я бы добавил, что '^' относится к началу строки, а '$' - к концу. Следовательно, '^. *: \ (. * \) $' Означает 'что-то до:, а затем остальные сохраняются в \ 1'. – fedorqui

Смежные вопросы