grepはn行のファイルをスキップし、それ以降の内容のみを検索します。

grepはn行のファイルをスキップし、それ以降の内容のみを検索します。

大量のログファイルがあり、最初に表示されるパターンを特定したら、別のパターンを探したいと思います。直後これが起こります。

たとえば、

123
XXY
214
ABC
182
558
ABC
856
ABC

182私の場合は見つけて探したい。Next起こったABC

最初は簡単です。

grep -n -m1 "182" /var/log/file

この出力は次のようになります。

5:182

ABCの次の発生を見つける方法は?

私の考えは、行番号182に基づいてgrep最初のn行(上記の例では)をスキップするように指示することです。しかし、どうすればいいですか?n=5

答え1

一度にsedrange および uit 入力を使用できます。q

sed '/^182$/p;//,/^ABC$/!d;/^ABC$/!d;q'

同様に、GNUではgrep入力を2つに分けることができますgrep

{ grep -nxF -m1 182; grep -nxF -m1 ABC; } <<\IN
123
XXY
214
ABC
182
558
ABC
856
ABC
IN

...印刷...

5:182
2:ABC

grep...見つかった最初の-F固定文字列リテラル、-x行全体を表します。182読み取りから始めて5行に一致し、2行目は同様のタイプを探します。アルファベット読み始めから2行一致 - または2行後ろに最初grep 辞める5行目をお読みください。

からman grep

-m NUM, --max-count=NUM
          Stop  reading  a  file  after  NUM  matching
          lines.   If the input is standard input from
          a regular file, and NUM matching  lines  are
          output, grep ensures that the standard input
          is  positioned  to  just  after   the   last
          matching  line before exiting, regardless of
          the  presence  of  trailing  context  lines.
          This  enables  a calling process to resume a
          search. 

再現可能なデモのためにここにあるドキュメントを使用しましたが、おそらく次のようにする必要があります。

{ grep ...; grep ...; } </path/to/log.file

次のような他のシェル複合コマンド構造とともに使用することもできます。

for p in 182 ABC; do grep -nxFm1 "$p"; done </path/to/log.file

答え2

grepPerl準拠の正規表現で使用されます()pcregrep

pcregrep -Mo '182(.|\n)*?\KABC'

オプションを使用すると、-Mパターンが複数行に一致し、一致する\Kパターン(これまで)を出力に含めないようにできます。\K領域全体をインポートするには削除できます。

答え3

> awk '/^182$/ { startline=1; }; startline == 0 { next; }; /^ABC$/ { print "line " NR ": " $0; exit; }' file
line 7: ABC

答え4

別のバリエーションは次のとおりです。

grep -n -A99999 "182" /var/log/file|grep -n -m1 "ABC"

フラグ - 何も見逃していないことを確認するために、マッチ後にgrep n行と99999を使用します。大きなファイルにはより多くの行が必要です(「wc -l」と確認)。

関連情報