我想在与“foo”匹配但不与“foobar”匹配的每一行周围打印 5 行上下文。
我可以通过很轻松地进行匹配,<output> | awk '/foo/ && !/foobar/'
但我不知道如何显示上下文<output> | grep -C 5 'foo'
。
grep
我也会满足于用一行代码来解决上述复合条件。
答案1
这是我在回答一个类似问题时得到的答案,但我再也找不到了:
awk -v context=5 '
BEGIN{ held = -1 }
{ for(i = context;i>0;i--)lb[i] = lb[i-1];
lb[0] = sprintf("%s:%d:%s",FILENAME,NR,$0);
held++;
}
/foo/ && !/foobar/{
if(held>context)held = context;
for(i = held;i>0;i--)print lb[i]
held = -1;
max = NR+context
}
{ if(NR<=max){ print lb[0]; held = -1 }
else{ if(held==context)print "--" }
}
'
如果你的 grep 是 gnu 并且执行 perl聚合酶链反应正则表达式,你可以这样做:
grep -P '(?!foobar)foo'
这意味着向前查找并且不匹配 foobar,后面跟着 foo。