web-dev-qa-db-ja.com

sedは一致しない行を無視します

どうすれば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に指示する方法です。それではどうすればいいのでしょうか?

79
Paggas

プレーンsedの別の方法:

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

s///は置換、tはラベルなしで後続のすべてのコマンドを条件付きでスキップし、dは行を削除します。

Perlやgrepは必要ありません。

(ニコラス・ライリーの提案後に編集)

80
liori

一致しない行を印刷したくない場合は、次の組み合わせを使用できます。

  • -n印刷しないようにsedに指示するオプション
  • pフラグ。一致するものを出力するようにsedに指示します

これは与える:

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

Perlを使用します。

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