一致しない行を無視してsedしました


91

sedある式に従ってフィルターの一致する行を作成し、一致しない行を印刷せずに無視するにはどうすればよいですか?

実際の例として、私scalacは一連のファイルで(Scalaコンパイラーを)実行し、その-verbose出力から.class作成されたファイルを読み取ります。scalac -verboseたくさんのメッセージを出力しますが、私たちはフォームのメッセージにのみ興味があります[wrote some-class-name.class]。私が現在やっていることはこれです(|&stashrを次のプログラムにパイプするための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います。つまり、入力から一致しない行を無視するように指示する方法です。それでは、どうすればよいでしょうか。


2
受け入れられた答えはmouvicielによるものである必要があります:stackoverflow.com/a/1665574/869951
Oliver

回答:


89

プレーンsedの別の方法:

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

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

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

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


3
OS X 10.8.2 では、セミコロンではなく改行で区切る必要がtxありdましたundefined label 'x;d;:x'
davidchambers

6
さらに良い:(同様の質問sed -e 's/.../.../' -e 'tx' -e 'd' -e ':x'に対するコメントで推奨)。
davidchambers

1
't'は、ラベルが指定されていない場合はスクリプトの最後に転送されるため、より単純ですsed -e 's/.../.../' -e 't' -e 'd'
ニコラスライリー

人々は-eオプションの意味を知らないので、一般的にそれについて言及しないでください。
Fredrick Gauss

242

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

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

これは与える:

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

3
このアプローチの1つの欠点は、一致する複数の式がある場合、結果も複数回出力されることです。例: echo foo | sed -n -e 's/foo/bar/p' -e 's/bar/oof/p'両方baroof別々の行に出力します。goto-labelバリエーションは、最初のパターンが一致しない場合に行を削除するため、複数のパターンも処理できません。
Rapsey

@Rapseyは、2回印刷するように指示しているためです。2回出力するように指示した単一のsedコマンドで、各インスタンスはその場で出力されます(またはバッファリングされる場合があります)。-eの代わりにパイプを使用するか、最後の-eに 'p'のみを指定する必要があります。
微生物

@Rapsey:この関連するポイントについての私の回答をご覧ください
アメシエル

@microbial、最後のpフラグが最後の置換式によって一致した各行で機能するため、機能しません。
アメシエル



0

Rapseyは、複数の代入式に関して関連するポイントを挙げました。

  • 最初に、Unix SEの回答を引用すると、「ほとんどのsedコマンドの前にアドレスを付けて、適用する行を制限できます」。
  • 次に、コマンドを中括弧{}(セミコロン;または改行で区切る)内でグループ化できます。
  • 3番目に、最後の置換に印刷フラグpを追加します

構文:

sed -n -e '/^given_regexp/ {s/regexp1/replacement1/flags1;[...];s/regexp1/replacement1/flagsnp}'

例(詳細はこちらのドキュメントを参照):

  • コード:

    sed -n -e '/^ha/ {s/h/k/gp;s/a/e/g}' <<SAMPLE
    haha
    hihi
    SAMPLE
    
  • 結果:

    kaka
    
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.