我有一个文件,该文件以以下方式记录了HTTP请求
POST pathX
header1: any
header2: any
header3: CONSTANT
POST pathX
header1: any
header2: any
POST pathX
header1: any
header2: any
header3: CONSTANT
...
我想找到所有在路径“ pathX”上且不包含header3的请求。
每个请求中带有标头的行数可以不同,
但通常是3或4。
我可以找到所有对pathX的请求,并显示下4行,如
cat file | grep "pathX" -A 4
这将找到所有3个请求,但是我真正想要的只是第二个没有"header3: CONSTANT"
行的请求。
答案 0 :(得分:1)
使用普通的grep正则表达式很难解决。但是,如果可以访问支持与Perl兼容的正则表达式(PCRE)的程序,例如pcregrep
,则可以执行以下操作:
pcregrep <file -M '(?s)^POST pathX(?:(?!^header3:).)*?(\n\n|\Z)'
-M
启用多行匹配(?s)
使.
与\n
匹配,因此我们不必写(\n|.)
(?!^header3:).
与任何在行首不以header3:
开头的字符匹配(?: ... )*?
匹配...
零次或多次,但尽可能少地使匹配成功(\n\n|\Z)
匹配空行或文件结尾答案 1 :(得分:1)
使用awk:
awk -v RS= '/pathX/ && !/header3/' file
使用您的输入文件,输出为:
$ awk -v RS= '/pathX/ && !/header3/' file
POST pathX
header1: any
header2: any
-v RS=
这告诉awk使用空行作为记录分隔符。这意味着每个请求(POST和标头)都作为一条记录读入。
/pathX/ && !/header3/
这告诉awk打印包含pathX
但不包含header3
的任何记录。