我如何更改下面的代码,以便打印符合以下条件的行,但仅当两个条件都为真时?
我需要提取的行必须符合以下条件:
仅打印与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