bash 如何grep,排除一些模式?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18468716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to grep, excluding some patterns?
提问by Loom
I'd like find lines in files with an occurrence of some pattern and an absence of some other pattern. For example, I need find all files/lines including loom
except ones with gloom
. So, I can find loom
with command:
我想在文件中找到出现某种模式而没有其他模式的行。例如,我需要查找所有文件/行,包括loom
带有gloom
. 所以,我可以loom
用命令找到:
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
Now, I want to search loom
excluding gloom
. However, both of following commands failed:
现在,我想搜索loom
排除gloom
. 但是,以下两个命令都失败了:
grep -v 'gloom' -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
grep -n 'loom' -v 'gloom' ~/projects/**/trunk/src/**/*.@(h|cpp)
What should I do to achieve my goal?
我应该怎么做才能实现我的目标?
EDIT 1:I mean that loom
and gloom
are the character sequences (not necessarily the words). So, I need, for example, bloomberg
in the command output and don't need ungloomy
.
编辑 1:我的意思是loom
和gloom
是字符序列(不一定是单词)。因此,例如,我需要bloomberg
在命令输出中而不需要ungloomy
.
EDIT 2:There is sample of my expectations. Both of following lines are in command output:
编辑 2:有我的期望样本。以下两行都在命令输出中:
I faced the icons that loomedthrough the veil of incense.
Arty is sloomingin a gloomyday.
我面对着透过香火的面纱若隐若现的圣像。
在阴沉的日子里,Arty隐隐约约。
Both of following lines aren't in command output:
以下两行不在命令输出中:
It's gloomyin'ower terrible — great muckle doolders o' cloods.
In the south west round of the heigh pyntit hall
这是gloomyin'奥尔可怕的-伟大的穆doolders O” cloods。
在 heigh pyntit 大厅的西南角
回答by houbysoft
How about just chaining the greps?
仅仅链接greps怎么样?
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
回答by Bentoy13
Another solution without chaining grep
:
另一个没有链接的解决方案grep
:
egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
Between brackets, you exclude the character g
before any occurrence of loom
, unless loom
is the first chars of the line.
在括号之间,您排除g
任何出现之前的字符loom
,除非loom
是该行的第一个字符。
回答by Sam
A bit old, but oh well...
有点旧,但哦,好吧...
The most up-voted solution from @houbysoft will not work as that will exclude any line with "gloom" in it, even if it has "loom". According to OP's expectations, we need to include lines with "loom", even if they also have "gloom" in them. This line needs to be in the output "Arty is slooming in a gloomy day.", but this will be excluded by a chained grep like
来自@houbysoft 的投票最多的解决方案将不起作用,因为它会排除任何带有“gloom”的行,即使它有“loom”。根据 OP 的期望,我们需要包含带有“loom”的线条,即使它们也带有“gloom”。这一行需要在输出“Arty is slooming in a grey day.”中,但这将被链接的grep排除在外
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
Instead, the egrep regexexample of Bentoy13works better
相反,Bentoy13的egrep regex示例效果更好
egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
as it will include any line with "loom" in it, regardless of whether or not it has "gloom". On the other hand, if it only has gloom, it will not include it, which is precisely the behaviour OP wants.
因为它将包含任何带有“loom”的行,无论它是否具有“gloom”。另一方面,如果它只有阴暗,则不会包括它,这正是 OP 想要的行为。
回答by Ed Morton
Just use awk, it's much simpler than grep in letting you clearly express compound conditions.
使用awk,它比grep简单得多,可以让您清楚地表达复合条件。
If you want to skip lines that contains both loom
and gloom
:
如果要跳过同时包含loom
and 的行gloom
:
awk '/loom/ && !/gloom/{ print FILENAME, FNR, awk '/(^|[^g])loom/{ print FILENAME, FNR, awk '/\<loom\>/{ print FILENAME, FNR, grep -vn "gloom" `grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)`
}' ~/projects/**/trunk/src/**/*.@(h|cpp)
}' ~/projects/**/trunk/src/**/*.@(h|cpp)
}' ~/projects/**/trunk/src/**/*.@(h|cpp)
or if you want to print them:
或者如果你想打印它们:
grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp) | xargs grep -vn "gloom"
and if the reality is you just want lines where loom
appears as a word by itself:
如果现实是你只想要单独loom
出现作为一个词的行:
grep -n "loom" `grep -l "loom" tt4.txt` | grep -v "gloom"
#this part gets the filenames with "loom"
#this part gets the lines with "loom"
#this part gets the linenumber,
#filename and actual line
回答by Oleg Kokorin
-v
is the "inverted match" flag, so piping is a very good way:
-v
是“反向匹配”标志,因此管道是一个非常好的方法:
grep "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)| grep -v "gloom"
grep "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)| grep -v "gloom"
回答by Juto
/*You might be looking something like this?
/*你可能看起来像这样?
grep -P '(?<!g)loom\b' ~/projects/**/trunk/src/**/*.@(h|cpp)
The BACKQUOTES are used like brackets for commands, so in this case with -l
enabled,
the code in the BACKQUOTES will return you the file names, then with -vn to do what you wanted: have filenames, linenumbers, and also the actual lines.
BACKQUOTES 就像命令的括号一样使用,因此在这种情况下-l
启用后,BACKQUOTES 中的代码将返回文件名,然后使用 -vn 执行您想要的操作:包含文件名、行号以及实际行。
UPDATEOr with xargs
更新或使用 xargs
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
Hope that helps.*/
希望有所帮助。*/
Please ignore what I've written above, it's rubbish.
请忽略我上面写的,这是垃圾。
[root@server]# cat file
1
2
3
4
5
回答by anubhava
You can use grep -P
(perl regex) supported negative lookbehind
:
您可以使用grep -P
(perl regex) 支持negative lookbehind
:
[root@server]# cat file |grep -v 3
1
2
4
5
I added \b
for word boundaries.
我添加\b
了单词边界。
回答by Jiminion
[root@server]# cat file |grep -v 3 |grep -v 5
1
2
4
回答by Tiborcz Kiss
Simply use! grep -v
multiple times.
简单使用!grep -v
多次。
Content of file
文件内容
grep -w 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
Exclude the line or match
排除行或匹配
##代码##Exclude the line or match multiple
排除该行或匹配多个
##代码##回答by Abhinandan
Question: search for 'loom' excluding 'gloom'.
Answer:
问题:搜索不包括 'gloom' 的 'loom'。
回答: