tim*_*tim 5 command-line grep search text-processing
我想在一个目录及其子目录中的所有文件中搜索包含某个字符串的行,但我想排除那些在紧随其后的行中包含不同的某个字符串的结果。
例如,这个:
foo1 searchString bar
foo1 excludeString bar
foo2 searchString bar
something else
foo3 searchString bar
foo3 excludeString bar
foo4 searchString bar
Run Code Online (Sandbox Code Playgroud)
应该返回这个:
foo2 searchString bar
foo3 searchString bar
foo4 searchString bar
Run Code Online (Sandbox Code Playgroud)
我知道-A
打印多行,并且-v
不包括结果。但我目前的做法grep -r -A 1 "searchString" | grep -v "excludeString"
显然行不通。
有没有办法告诉第二个 grep 如果找到匹配项,它也应该删除前一行?或者我如何以其他方式实现这一目标?
性能不是我最关心的问题;不过,如果命令相对容易记住,那就太好了。
您可以使用p
ERL c
ompatible r
egular e
Xpressions的grep
:
$ pcregrep -M '(searchString.*\n)(?!.*excludeString)' file
foo2 searchString bar
foo3 searchString bar
foo4 searchString bar
Run Code Online (Sandbox Code Playgroud)
它搜索searchString
后跟任何字符.
,重复零次或多次*
,\n
仅当旁边没有( ?!
) 模式时才搜索新行.*excludeString
。-M
存在选项以匹配多行。
与sed
:
sed '/searchString/!d;$!N;/\n.*excludeString/!P;D' infile
Run Code Online (Sandbox Code Playgroud)
这个怎么运作:
/searchString/!d
如果不匹配则删除该行searchString
并在新行中读取,重新开始命令循环(即不再执行剩余的命令)searchString
,则sed
执行$!N;/\n.*excludeString/!P;D
- 在这里查看它是如何工作的;不同之处在于,它在这里寻找ewline 字符excludeString
之后的模式,\n
以便匹配两者的行searchString
,excludeString
如果后面没有匹配的行,则仍会打印excludeString
;如果没有与searchString
和excludeString
(即已知输入)匹配的行,那么您可以删除该\n.*
部分并运行:sed '/searchString/!d;$!N;/excludeString/!P;D' infile