どうすればsed
を式に応じて一致する行にフィルターをかけることができますが、一致しない行を印刷せずに無視できますか?
実際の例として、一連のファイルに対してscalac
(Scalaコンパイラ))を実行し、その-verbose
出力.class
ファイルが作成されました。 scalac -verbose
は大量のメッセージを出力しますが、関心があるのは[wrote some-class-name.class]
。私が現在やっていることはこれです(|&
は、stderrを次のプログラムにパイプするbash 4.0の方法です)。
$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/'
これにより、関心のあるメッセージからファイル名が抽出されますが、他のすべてのメッセージも変更せずに通過できます!もちろん、代わりにこれを行うことができます:
$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
sed 's/^\[wrote \(.*\.class\)\]$/\1/'
これは機能しますが、実際の問題を回避するように見えます。つまり、入力からの一致しない行を無視するようにsed
に指示する方法です。それではどうすればいいのでしょうか?
プレーンsedの別の方法:
sed -e 's/.../.../;t;d'
s///
は置換、t
はラベルなしで後続のすべてのコマンドを条件付きでスキップし、d
は行を削除します。
Perlやgrepは必要ありません。
(ニコラス・ライリーの提案後に編集)
一致しない行を印刷したくない場合は、次の組み合わせを使用できます。
-n
印刷しないようにsedに指示するオプションp
フラグ。一致するものを出力するようにsedに指示しますこれは与える:
sed -n 's/.../.../p'
Perlを使用します。
... |& Perl -ne 'print "$1\n" if /^\[wrote (.*\.class)\]$/'