sed - Получить только замененную строку из многострочного ввода и пропустить непревзойденные строки! - PullRequest
17 голосов
/ 05 апреля 2011

Я хочу, чтобы sed опускал все несоответствующие строки и выводил только замененную строку (из одной / нескольких предполагаемых строк / с).

Другими словами: У меня есть стог сена, и я хочу только вернуть иглу, а не все сено, которое было обыскано и которое осталось неизменным.

Или, другими словами: Поиск/ заменить строку, описанную RegEx, в многострочную строку и вернуть только эту строку.(Как это возможно с помощью функции PHP http://www.php.net/manual/en/function.preg-replace.php)

Мой текущий обходной путь - сначала отфильтровать с помощью grep, а затем передать только совпадающие строки в sed для замены:

echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | egrep "^Important1.*$" | sed -E "s/^Important1: *\b(.*)\b */\1/g"
# From the multiple line input I only want the "One One" (with pre/post whitespace removed, hence matching the word boundaries with "\b")
# And I want no "Bla bla" lines in the result!

Но я бы хотел иметь одно решение в рамках sed .Или это не по назначению sed, и я должен поэтому лучше использовать что-то еще?Кстати, вопрос: многострочный sed с использованием обратных ссылок , похоже, как-то связан, но я не уверен!

Ответы [ 3 ]

13 голосов
/ 05 апреля 2011

РЕДАКТИРОВАТЬ: Следующее было протестировано на Mac и Linux.

Вы можете использовать sed следующим образом:

echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | \
   sed -n 's/^Important1: *\([^ ]*\) */\1/p'

OUTPUT:
one

Объяснение

sed -n 's/^Important1: *\([^ ]*\) */\1/p'

-n # quiet / silent 

{
  s/^Important1: *\([^\ ]*\) */\1/ # replace "Important1: one " with 1st group i.e. "one"
  p                  # print the replaced text
}
6 голосов
/ 05 апреля 2011

Эта команда sed делает то, что делает ваша комбинация egrep и sed:

echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla"
| sed -n -e "s/^Important1: *\b\(.*\)\b */\1/p"

Вы выполняете подстановку и выводите только совпадающие строки после подстановки.

4 голосов
/ 05 апреля 2011
sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'

Подтверждение концепции

$ echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'
One
...