一致するパラメータの上の3行を取得する方法

一致するパラメータの上の3行を取得する方法

ログファイル内の一致するパラメータの上に3行を印刷したいと思います。次のコマンドを使用していますが、エラーが発生します。代替案はありますか?

grep -A 3 "例外" Services.log

次のエラーが発生します。

grep: Not a recognized flag: A
Usage: grep [-r] [-R] [-H] [-L] [-E|-F] [-c|-l|-q] [-insvxbhwyu] [-p[parasep]] -e pattern_list...
        [-f pattern_file...] [file...]

答え1

次のawkコマンドは、文字列exceptionと「コンテキストの前」の3行を含む行を提供します(-B 3GNUgrepおよび他のgrep実装を使用)。

awk 'BEGIN { bc=3 } { lines[NR%(bc+1)] = $0 } /exception/ { for (i=1; i<=(bc+1); ++i) print lines[(NR+i)%(bc+1)] }' file

linesこれにより、必要な「コンテキスト前」行数である行bc+1の「円形バッファ」が維持されます。bc行がパターンと一致すると、そのexceptionバッファの内容が印刷されます。

これは、一致が発生した場合を正しく処理しません。以内にbc他の一致の「前のコンテキスト」または最初の一致がファイルの行数より少なく発生するファイルの場所。

特定のパターンの前後に設定可能な量のコンテキストを提供するスクリプトに一般化されました。

#!/bin/sh

# Usage:
#    ./script [ -A n ] [ -B n ] PATTERN FILE ...

after=0
before=0

while getopts 'A:B:' opt; do
    case $opt in
    A)
        after=$OPTARG
        ;;
    B)
        before=$OPTARG
        ;;
    *)
        echo 'error in command line parsing' >&2
        exit 1
    esac
done
shift "$(( OPTIND - 1 ))"

pattern=$1
shift

pattern=$pattern awk -v bc="$before" -v ac="$after" '
    { lines[NR%(bc+1)] = $0 }
    $0 ~ ENVIRON["pattern"] {
        for (i=1; i<=(bc+1); ++i) print lines[(NR+i)%(bc+1)]
        print_after=ac
        next
    }
    print_after > 0 { print; print_after-- }' "$@"

テストしてみてください:

$ cat file
1
2
3
4
5
exception
6
7
8
9
0
exception
$ sh script.sh -B 3 exception file
3
4
5
exception
8
9
0
exception
$ sh script.sh -A 3 exception file
exception
6
7
8
exception
$ sh script.sh -A 1 -B 1 exception file
5
exception
6
0
exception

答え2

シンプルだが必ずしも効果的ではない。

tac Services.log | awk '/exception/ {L = NR + 4} NR < L' | tac

関連情報