awk 提取两个模式匹配的行均为 true

awk 提取两个模式匹配的行均为 true

我如何更改下面的代码,以便打印符合以下条件的行,但仅当两个条件都为真时?

我需要提取的行必须符合以下条件:
仅打印与patterna匹配的行,如果找到满足patternb条件的行。

awk '/patterna/ || /patternb/ { print > "patternapatternb.txt" }' inputfile

输入文件
模式a 这个
模式b 那个
模式a 那个
模式a
另一个模式
模式a 另一个这个
模式b 另一个那个

输出patternapatternb.txt:
patterna这个
patternb那个
patterna anotherthispatternb
anotherthat

以及如何对多对模式实现这一点,以便能够将每对的输出写入不同的文件

答案1

awk分别处理每个记录(默认情况下,一个记录是一行) - 要应用跨越相邻行的条件,您可以使用该getline函数读取下一个记录并根据第二个模式进行测试:

awk '/patterna/ { 
  a=$0
  if (getline > 0 && $0 ~ /patternb/) {
    print a
    print
  }
}' inputfile

或者,您可以考虑使用sed

sed -n '/patterna/ {$!N; /\npatternb/p}' inputfile

如果您想/patternb/在 的每次匹配之后打印第一个匹配项/patterna/,前面是它/patterna/,那么您可以制作一个有状态的解析器通过在每次匹配时设置一个标志/patterna/并在每次匹配时取消设置它/patternb/

awk '
  /patterna/ {
    a=1; lasta=$0; next;
  } 
  /patternb/ && a==1 {
     a=0; print lasta; print;
  }' inputfile

答案2

使用中非常干净的解决方案TXR,除了输出之外没有显式的状态操作或副作用:

@(repeat)
patterna @this
@  (repeat)
patterna @other
@    (fail)
@  (last :mandatory)
patternb @that
@  (end)
@  (output)
patterna @this
patternb @that
@  (end)
@(end)

跑步:

$ txr pairs.txr data
patterna this
patternb that
patterna anotherthis
patternb anotherthat

在此解决方案中,我们尝试捕获此要求:patternb在带有 的行之后找到关键字patterna。它不必是紧随其后的一行。但是,patternb必须在另一行出现之前发生,该行具有patterna:在给定patterna行与其匹配patternb对行之间,不能有另一patterna行。

内部迭代:

@  (repeat)
patterna @other
@    (fail)
@  (last :mandatory)
patternb @that
@  (end)

扫描输入,寻找两件事:匹配

patterna @other

或强制终止匹配

patternb @that

但是,如果patterna @other找到,则紧随其后的下一个指令将@(fail)导致重复失败。 (重复建立隐式@(block)@(fail)导致最内层的封闭块作为失败的匹配而终止。)

答案3

好的,根据您更全面的解释,您可以使用 pcregrep

pcregrep -M 'patterna(.*\n)patternb' inputfile > patternapatternb.txt

这条单线会给你

cat patternapatternb.txt
patterna this
patternb that
patterna another this
patternb another that

之前的回复

我用了这个单行代码...

 awk '/patterna/ && /patternb/ {print > "patternapatterb.txt" } ' inputfile

这个输入文件

cat inputfile
patterna    patternb    this
patterna    patterna    that

结果是

cat patternapatterb.txt
patterna    patternb    this

这似乎正是您所要求的(您说“但仅当两者都为真时”);但是,如果我们误解了您的请求,请告知我们。

如果你想匹配patterna或patternb,你可以使用egrep

 egrep "patterna||patternb" inputfile > patternapatternb.txt

相关内容