如何grep查找缺少的行

时间:2019-01-31 22:50:28

标签: grep text-processing

我有一个文件,该文件以以下方式记录了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"行的请求。

2 个答案:

答案 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的任何记录。