关于bash:grep不包括文件名模式

grep excluding file name pattern

我读过使用grep--exclude/--include语法在某些文件中不grep但在我的中心6.4,当我这样做的时候

1
grep --exclude=*.cmd ckim * -r

我看到很多来自*.cmd文件的grepped行。因此,排除选项似乎对我不起作用。怎么了?我当然可以做像

1
grep ckim \`find . -name \*.c -print\`

但我想知道为什么grep不起作用。


您可以引用模式:

1
grep -r --exclude="*.cmd" "ckin" ./

ps../是当前目录


使用.作为路径规范,而不是*

1
grep -r --exclude \*.cmd ckim .


I see lots of grepped lines from *.cmd files. So it seems the exclude option is not working for me.

有一个名为nullglob的shell选项,它控制没有匹配文件时shell模式的扩展。

因此,考虑到以下环境:

1
2
3
4
sh$ touch f.cmd g.sh
sh$ mkdir sub
sh$ echo ckim > sub/h.cmd
sh$ echo ckim > sub/i.cmd

在我的系统上(其中nullglob未设置),以下命令:

1
grep --exclude=*.cmd ckim * -r

由壳牌公司扩展("理解")为:

1
grep --exclude=*.cmd ckim f.cmd g.sh sub -r

也就是说,我将递归地(-r搜索字符串skim,从f.cmdg.shsub开始,但不包括任何与模式'*.cmd'匹配的文件。

结果是:

1
2
3
# nullglob is unset
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim

但是,如果在您的环境中设置了选项nullglob,则相同的命令扩展到:

1
grep ckim f.cmd g.sh sub -r

注意整个--exclude=...是如何消失的。结果是:

1
2
3
4
# nullglob is set
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
sub/h.cmd:ckim

现在,解释一下。当shell遇到一个glob模式(即包含*?或一些更特殊的字符)时,它用匹配的文件扩展它。但是如果没有匹配的文件,它要么让模式保持原样(如果没有设置nullglob),要么用"无"替换(如果设置了nullglob)。

这里的模式是--include=*.cmd,因为里面没有空间。在不太可能的情况下,您有一个与此模式匹配的文件,它将被替换。否则,它要么"按原样"或完全删除——这取决于nullglob

您可以轻松地显示、设置(-s或取消设置(-u当前bash的nullglob选项的状态:

1
2
3
4
5
6
7
8
9
10
sh$ shopt nullglob
nullglob        on

sh$ shopt -u nullglob
sh$ shopt nullglob
nullglob        off

sh$ shopt -s nullglob
sh$ shopt nullglob
nullglob        on

你也可以这样做

1
grep -rn ckim * | grep -v '\.cmd'


如果要从grep中排除某些文件,则应使用-l选项。

1
grep -l --exclude=*.cmd ckim * -r