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 для расширенных конструкций (обратные ссылки, неживые операторы). Я позволю вам сделать перевод, если вам нравится подход.