Подтвердить что ты не робот

Попросите 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 игнорировать несогласованные строки от ввода. Итак, как мы это делаем?

4b9b3361

Ответ 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'

Нет необходимости в замене.