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
一致しない行を印刷したくない場合は、次の組み合わせを使用できます。
-n
sedに印刷しないように指示するオプションp
sedに一致したものを出力するように指示するフラグ
これは与える:
sed -n 's/.../.../p'
さらに、先行する一致パターンを使用して、/match only these lines/
このパターンに一致する行にのみ置換コマンドを適用することもできます。
これは与える:
sed -n '/.../ s/.../.../p'
例えば:
# replace all occurrences of `bar` with `baz`
sed -n 's/bar/baz/p'
# replace `bar` with `baz` only on lines matching `foo`
sed -n '/foo/ s/bar/baz/p'
参照この他の答えアドレッシングラプシーのコメントは以下複数の交換について