带范围的 Grep 并通过三个过滤器

带范围的 Grep 并通过三个过滤器

我有一个文件sample.txt

-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:RAM      SAM 
    XY       DUPL
    KEY:UU
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------

我根据关键字过滤订单ord:chandrukey:ZZ如果找到这些出现的情况,我将删除从连字符到连字符开始的订单,以给出这样的输出

-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------

答案1

如果你有 GNUawk我建议这样:

gawk 'BEGIN{RS="-+\n"} $0=="" || /ord:chandru/ && /KEY:ZZ/ {ORS=RT; print}' sample.txt
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------

just强制$0==""打印空记录(如果您认为记录是由连字符字符串分隔的话,这就是文件第一行的解释方式)。


如果你gawk,那么真正唯一的区别是您无法轻松捕获记录分隔符 - 在您提供的示例中这不是一个大问题,因为它是一个固定字符串。例如mawk

mawk 'BEGIN{RS="-------------\n"; ORS=RS} $0=="" || /ord:chandru/ && /KEY:ZZ/ {print}' sample.txt
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------

答案2

这个应该是比较靠谱的

$ sed -n '1p; /ord:chandru/ {             
N                                           
N
/KEY:ZZ/{
N
/ord:chandru.*\n.*\n.*KEY:ZZ.*\n---.*/p
}
}' file

解释

  • -n在我们提出要求之前不要打印
  • 1p打印第一行,假设这会给我们一行连字符(此后,我们只打印连字符的尾部行)
  • /ord:chandru/找到模式
  • N读取下一行以允许我们使用该\n字符来表示换行符
  • p打印匹配的行

答案3

使用awk

$ awk 'BEGIN{RS="-------------"};/KEY:ZZ/&&/ord:chandru/{print RS$0}' sample.txt|egrep -v "^ *$"

输出:

-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:Z    
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ

答案4

sed -e '
   /^ord:/,/^--*$/!b
   H; /^ord:/h
   /^--*$/!d; g
   /^ord:chandru[ ]/!d
   /\n[ ]*KEY:ZZ\n--*$/!d
'  sample.txt

简要摘要: /../,/../=> 是范围运算符,用于选择一系列行,就像您的情况一样 from /ord:/ to /----/

我们松鼠将这些范围(一次一个范围)摇晃到保持区域。然后,当我们到达 range 的末尾时/---/,我们知道是时候根据 `a) /ord:chandru/ && b) /key:ZZ/' 的标准来选择或拒绝这个特定范围了。

相关内容