ランダム文字列の最初のインスタンスから最後のインスタンスまでファイルの内容を取得します。

ランダム文字列の最初のインスタンスから最後のインスタンスまでファイルの内容を取得します。

lessランダム文字列 "foo"の最初のインスタンスから最後のインスタンスまでどのように表示できますか?

このランダムな文字列は、ログのほぼすべての行に表示されます。grep "foo" bar.log | lessすべての関連行には表示されないため、これを実行したくありません。

ファイルが次のようになるとします。

1 Random junk I don't want to see
2 Care about (foo)
3 Care about (foo)
4 Care about
5 Care about (foo)
6 Other random junk I don't want to see

残念ながら、無視したい行は良いパターンに従わない。そうでなければちょうどgrep -v 'insert pattern here'

lessどういうわけか、次の内容を統合する方法を知りたいです。

2 Care about (foo)
3 Care about (foo)
4 Care about
5 Care about (foo)

grep "foo" bar.log | less私は興味のある4行を無視しているので動作しません。

答え1

ある場合はawk、次のようにできます。

awk '/foo/{print b$0;b="";x=1;next} x{b=b$0"\n"}' bar.log | less

aがfoo表示されたら、バッファ(b変数)と現在の行を印刷してバッファを消去します。

fooそれ以外の場合は(変数)がすでに存在する場合にのみ、x現在の行をバッファリングします。

答え2

これには慎重なシェル引用が必要ですが、できるedこれを行うには、スクリプト可能なエディタを使用してください。

printf '%s\n' "/foo/ka" "??" "'a,.w "'!less' q | ed -s file

これにより、次のアドレスに4つのコマンドが送信されますed

  1. /foo/ka- 最初の一致でfooパターンを検索し(ファイルの先頭で)、名前付きタグを設定しますa
  2. ??- 検索をファイルの末尾で逆さまに繰り返します。ここで重要な副産物は、現在の行を対応する(最後の)一致として設定することです。
  3. 'a,.w !lessa- 現在の行()で指定されたタグから、.次の行をシェルコマンド(!)に書き込みますless
  4. q——編集を終了します。

less終了するには正常に(q)終了する必要がありますed。この解決策は、パターンがファイルに少なくとも一度存在すると仮定します。それ以外の場合、検索は失敗し、?終了する前に3を取得します。ed

答え3

一致する行を含める代わりにgrepを使用して除外しますか?その場合は、以下を試してください。grep -v "Don't care about"

関連情報