Попросите sed игнорировать несогласованные строки
Как я могу сделать sed
соответствие строк соответствия фильтрам в соответствии с некоторым выражением, но игнорировать несогласованные строки, а не разрешать их печать?
В качестве реального примера я хочу запустить scalac
(компилятор Scala) в наборе файлов и прочитать из его -verbose
вывод созданных файлов .class
. scalac -verbose
выводит кучу сообщений, но нас интересуют только те формы [wrote some-class-name.class]
.
То, что я сейчас делаю, это (|&
есть bash 4.0 способ передать stderr в следующую программу):
$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/'
Это приведет к извлечению имен файлов из сообщений, которые нас интересуют, но также позволит передавать все остальные сообщения без изменений! Конечно, мы могли бы сделать это:
$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
sed 's/^\[wrote \(.*\.class\)\]$/\1/'
который работает, но очень похож на реальную проблему, а именно, как проинструктировать sed
игнорировать несогласованные строки от ввода. Итак, как мы это делаем?
Ответы
Ответ 1
Другой способ с простым sed:
sed -e 's/.../.../;t;d'
s///
является заменой, t
без какой-либо метки условно пропускает все последующие команды, d
удаляет строку.
Нет необходимости в perl или grep.
(отредактировано после предложения Николаса Райли)
Ответ 2
Если вы не хотите печатать строки, которые не совпадают, вы можете использовать комбинацию
-
-n
, который сообщает sed не печатать
-
p
флаг, который сообщает sed распечатать то, что соответствует
Это дает:
sed -n 's/.../.../p'
Ответ 3
Использовать Perl:
... |& perl -ne 'print "$1\n" if /^\[wrote (.*\.class)\]$/'
Ответ 4
sed -n '/.../!p'
Нет необходимости в замене.