регулярное выражение (sed) подавляет вывод "нет совпадения" - PullRequest
18 голосов
/ 16 мая 2011

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

Это действительно за граньюя: Почему sed возвращает всю строку, если он ничего не нашел?Нужно ли запускать другой тест для возвращенной строки, чтобы проверить это?Я попытался использовать «-n» на (очень короткой) странице справки, но он эффективно подавляет весь вывод, включая совпадающие строки.

Это то, что у меня сейчас есть:

echo plop-02-plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/'

, которое возвращает02 (и это прекрасно и здорово, большое спасибо), но:

echo plop-02plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/'

возвращает plop-02plop (когда он должен вернуть это = "" ничто ! Dang, вы ничего не нашли, так что молчите! За громкий крик !!)

Я пытался проверить возвращаемое значение, но и это не удалось!Вздох !!

$ echo plop-02-plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/' ; echo $?
02
0
$ echo plop-02plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/' ; echo $?
plop-02plop
0
$

Это последнее, в которое я даже не могу поверить.sed действительно ли инструмент, который я должен использовать?Я хочу извлечь иголку из стога сена, и я хочу иглу или ничего ..?

Ответы [ 2 ]

24 голосов
/ 16 мая 2011

sed по умолчанию печатает все строки.

То, что вы хотите сделать, это

/patt/!d;s//repl/

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

sed -e '/^.*\(.\)\([0-9][0-9]\)\1.*$/!d;s//\2/'

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

sed -ne 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/p'

Существует также grep, но ваш пример показывает, почему sed иногда лучше.

2 голосов
/ 16 мая 2011

Возможно, вы можете использовать egrep -o?

input.txt:

blooody
aaaa
bbbb
odor
qqqq

1007 * Е.Г. *

sehe@meerkat:/tmp$ egrep -o o+ input.txt 
ooo
o
o
sehe@meerkat:/tmp$ egrep -no o+ input.txt 
1:ooo
4:o
4:o

Конечно, egrep будет иметь немного другой (лучше?) Синтаксис регулярных выражений для сложных конструкций (обратные ссылки, не жадные операторы). Я позволю вам сделать перевод, если вам нравится подход.

...