Regexp (sed) подавляет вывод "без соответствия"

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

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

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

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 (когда он должен вернуть это = "" ничего! Данг, ты ничего не нашел, так что будь тихим!  Для крика вслух!!)

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

$ 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 инструментом, которым я должен пользоваться? Я хочу извлечь иглу из стога сена, и я хочу иглу или ничего.?

Ответы

Ответ 1

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

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

input.txt:

blooody
aaaa
bbbb
odor
qqqq

например.

[email protected]:/tmp$ egrep -o o+ input.txt 
ooo
o
o
[email protected]:/tmp$ egrep -no o+ input.txt 
1:ooo
4:o
4:o

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