Answers:
您可以grep
与-P
(PCRE)一起使用:
grep -P -A 1 'SomeTest(?!AA)' file.txt
(?!AA)
是零宽度负先行图案,确保没有AA
after SomeTest
。
测试:
$ grep -P -A 1 'SomeTest(?!AA)' file.txt
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest
\.
这样grep -P -A 1 'SomeTest\.(?!AA)' file.txt
或grep -P -A 1 'SomeTest(?!\.AA)' file.txt
SomeTest*\nEndTest
因此您实际上对grep
所有匹配的行执行ping操作,SomeTest*
但SomeTestAA
在匹配之后却不+一行上下文。在输入中添加更多行(例如,foobar
在每EndTest
行之后添加一行),然后重试。
这是可与任意输入sed
配合使用的解决方案(-n
即不进行自动打印):
sed -n '/SomeTestAA/!p # if line doesn't match, print it
: m # label m
//{ # if line matches
$!{ # and if it's not the last line
n # empty pattern space and read in the next line
b m # branch to label m (so n is repeated until a
} # line that's read in no longer matches) but
} # nothing is printed
' infile
所以输入像
SomeTestAAXX
SomeTestAAYY
+ one line
SomeTestONE
Message body
EndTest
########
SomeTestTWO
something here
EndTest
SomeTestAABC
+ another line
SomeTestTHREE
EndTest
SomeTestAA
+ yet another line
跑步
sed -n -e '/SomeTestAA/!p;: m' -e '//{' -e '$!{' -e 'n;b m' -e '}' -e'}' infile
输出
SomeTestONE
Message body
EndTest
########
SomeTestTWO
something here
EndTest
SomeTestTHREE
EndTest
也就是说,它会完全删除grep -A1 SomeTestAA infile
将选择的行:
SomeTestAAXX
SomeTestAAYY
+ one line
--
SomeTestAABC
+ another line
--
SomeTestAA
+ yet another line
//
匹配/SomeTestAA/
。我认为,在这种情况下,它将与否定的表达式匹配:/SomeTestAA/!
。(+1)
!
不是RE的一部分,而是sed
一回事。
将多行区域视为单个记录的东西可能会更好。这里有一个sgrep
我还没有使用太多。
还有awk,您可以在其中将输入记录分隔符和输出记录分隔符设置为任意值。
pat="^SomeTestAA"
awk 'BEGIN{ RS=ORS="\nEndTest\n"} !/'"$pat/" foo
大多数awk程序都用单引号引起来,但是我在结尾处更改为双引号,以便$pat
可以扩展shell变量。
awk -vpat="^SomeTestAA" -vRS="\nEndTest\n" 'BEGIN{ ORS=RS } $0 !~ pat' file
一种选择是使用p
ERL c
ompatible r
egular e
上的表达grep
:
pcregrep -Mv 'SomeTestAA.*\n' file
该选项-M
允许模式匹配多于一行。
grep
已经支持PCRE(通过-P
选件),使用的好处是pcregrep
什么?
grep
不支持该-M
选项。
尝试了下面的sed命令,它工作正常
命令
sed '/SomeTestAA/,+1d' filename
输出
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest