我需要在'错误:'之前找到最近出现的'GET'(GET zzzz)并捕获其中的所有文本。
GET xxxxx
GET yyyyy
GET zzzzz
Some text
more text
error: this is an error
可以这样做吗?
谢谢,awk解决方案有效,但是通过最后出现'错误:'可以进一步改善吗?
GET xxxxx
GET yyyyy
GET zzzzz
Some text
more text
error: this is the first error
GET xxxxx
GET yyyyy
GET zzzzz
Some text
more text
error: this is the last error
答案 0 :(得分:3)
尝试以下awk
解决方案:
awk '
/^GET/ { delete lines; c=0; inBlock=1 }
/^error:/ { for(i=1; i<=c; ++i) print lines[i]; print; exit }
inBlock { lines[++c] = $0 }
' file
这假定只打印 1 块,并且还应打印error:
行。 (更新:请参阅下面的解决方案,仅打印最后块)。
/^GET/ { delete lines; c=0; inBlock=1 }
开始在变量lines
中构建一系列行,只要在行的开头遇到字符串GET
。/^error:/ { for(i=1; i<=c; ++i) print lines[i]; print; exit }
在该行的开头匹配字符串error:
,并打印出目前为止构建的所有行,然后是当前行,然后退出。inBlock { lines[++c] = $0 }
将以最新GET
行开头的每一行添加到数组中。更新:
要报告(仅)以error:
结尾的 last 块,请使用以下命令:
awk '
/^GET/ { delete lines; c=0; inBlock=1 }
inBlock { lines[++c] = $0 }
/^error:/ { inBlock=0; }
END { for(i=1; i<=c; ++i) print lines[i] }
' file
这与第一个解决方案的不同之处在于,后面的块只是简单地替换了之前的块,以便最后一个块“wins”,然后在Awk脚本的END
块中处理完所有输入后打印
答案 1 :(得分:1)
假设:
$ echo "$tgt"
first line
second line
GET xxxxx
GET yyyyy
GET zzzzz
Some text
more text
error: this is the first error
GET xxxxx
GET yyyyy
GET zzzzzLAST
Some text
more text
error: this is the last error
last line
你可以有一个多行正则表达式,它将丢弃所有字符,直到最后一个所需的块,如下所示:
/^.*^(GET.*^error[^\n]*)/ms
现在使用Perl,读取整个文件并与之匹配。 -0777
命令行选项将导致读取整个文件:
$ echo "$tgt" | perl -0777 -ne 'print $1 if m/^.*^(GET.*^error[^\n]*)/sm'
GET zzzzzLAST
Some text
more text
error: this is the last error
如果要包含超出最后一个“错误”行的行,请将正则表达式更改为:
/\A.*^(GET.*^error.*)\Z/ms
Perl:
$ echo "$tgt" | perl -0777 -ne 'print $1 if m/\A.*^(GET.*^error.*)\Z/ms'
GET zzzzzLAST
Some text
more text
error: this is the last error
last line
答案 2 :(得分:-1)