Есть ли sed игнорировать несоответствующие строки


как я могу сделать sed фильтровать совпадающие строки в соответствии с некоторым выражением, но игнорировать несоответствующие строки, вместо того, чтобы позволить им печатать?

в качестве реального примера, я хочу запустить scalac (компилятор Scala) на набор файлов, и читать из его -verbose вывод файлы. scalac -verbose выводит кучу сообщений, но нас интересуют только те формы [wrote some-class-name.class]. Что я сейчас делаю это (|& это путь bash 4.0 к трубе stderr к следующему программа):

$ scalac -verbose some-file.scala ... |& sed 's/^[wrote (.*.class)]$//'

это извлечет имена файлов из сообщений, которые нас интересуют, но также позволит всем другим сообщениям проходить без изменений! Конечно, мы могли бы сделать вместо этого:

$ scalac -verbose some-file.scala ... |& grep '^[wrote .*.class]$' |
  sed 's/^[wrote (.*.class)]$//'

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

3 67
sed

3 ответа:

другой способ с простым sed:

sed -e 's/.../.../;t;d'

s/// - это замещения, t без какой-либо метки условно пропускает все следующие команды, d удаляет линии.

нет необходимости в perl или grep.

(отредактировано после предложения Николаса Райли)

Если вы не хотите печатать строки, которые не совпадают, вы можете использовать комбинацию

  • -n опция, которая говорит sed не печатать
  • p флаг, который говорит sed печатать то, что соответствует

Это дает:

sed -n 's/.../.../p'

Использовать Perl:

... |& perl -ne 'print "\n" if /^\[wrote (.*\.class)\]$/'