我想在日志文件中打印匹配参数上方的 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
以及三行“before context”(-B 3
使用 GNUgrep
和其他一些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