grep 排除文件名模式
Posted
技术标签:
【中文标题】grep 排除文件名模式【英文标题】:grep excluding file name pattern 【发布时间】:2014-09-10 08:05:46 【问题描述】:我读过 Use grep --exclude/--include syntax to not grep through certain files 但在我的 CentOS6.4 中,当我这样做时
grep --exclude=*.cmd ckim * -r
我从 *.cmd 文件中看到很多 grepped 行。 所以似乎排除选项对我不起作用。 怎么了? 当然我可以做类似的事情
grep ckim \`find . -name \*.c -print\`
但我想知道为什么 grep 不起作用。
【问题讨论】:
你需要包含pattern
参数。
【参考方案1】:
你可以引用模式:
grep -r --exclude="*.cmd" "ckim" ./
PS。 ./
是当前目录
【讨论】:
除非 OP 设置了nullglob
,否则这不会产生显着差异。 --exclude=*.cmd
不太可能匹配单个文件,并且将保持原样作为参数。这是正确的做法,但没有给出解决方案。
@konsolebox,我必须承认我对nullglob
了解不多,但shopt
说它是off
并且仍然有效。我错过了什么吗?
它应该可以工作,但即使没有引用它仍然可以。实际上我的假设可能是错误的,并且您的代码实际上可能能够帮助解决问题 - 不是因为您帮助它防止自身扩展到文件,而是因为您帮助防止它在 @987654328 时失效@ 已启用。由于引用,可以防止任何类型的路径名扩展。我不敢相信我真的忽略了那部分。【参考方案2】:
使用.
代替*
作为路径规范。
grep -r --exclude \*.cmd ckim .
【讨论】:
在我的测试中,即使使用了*
,该命令仍然有效。显式文件参数仍会被过滤。
@konsolebox: 用 Ubuntu 确认
我认为.
和-r
更清晰,不会导致不必要的外壳扩展行为。
@konsolebox: 使用 RHEL7 确认【参考方案3】:
你也可以这样做
grep -rn ckim * | grep -v '\.cmd'
【讨论】:
这有不想要的行为,想象一下文件内的行有something.cmd
,即使文件名不包含\.cmd
,它也不会显示该行
是的,它有一些不受欢迎的行为......但是在同一行使用 '.cmd' 发生 ckim 的可能性要小得多【参考方案4】:
我从 *.cmd 文件中看到很多 grepped 行。所以看来排除选项对我不起作用。
有一个名为nullglob
的shell 选项可以在没有匹配文件时控制shell 模式的扩展。
所以,给定以下环境:
sh$ touch f.cmd g.sh
sh$ mkdir sub
sh$ echo ckim > sub/h.cmd
sh$ echo ckim > sub/i.cmd
在 my 系统上(nullglob
未设置),以下命令:
grep --exclude=*.cmd ckim * -r
被外壳扩展(“理解”)为:
grep --exclude=*.cmd ckim f.cmd g.sh sub -r
也就是说,我将递归地 (-r
) 搜索以f.cmd
、g.sh
和g.sh
和sub
开头的字符串skim
,但不包括与模式'* 匹配的任何文件.cmd'。
结果是:
# nullglob is unset
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
但是如果在您的环境中设置了选项nullglob
,则相同的命令扩展为:
grep ckim f.cmd g.sh sub -r
注意整个 --exclude=...
是如何消失的。所以结果是:
# nullglob is set
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
sub/h.cmd:ckim
现在,解释一下。当 shell 遇到 glob 模式(即:包含 *
或 ?
或更多特殊字符)时,它会使用匹配的文件对其进行扩展。 但是如果没有匹配的文件,它要么让模式保持原样(如果nullglob
没有设置)或者用“nothing”替换它(如果nullglob
已设置)。
这里的模式是--include=*.cmd
(在整个,因为那里没有空间)。万一您有一个与此模式匹配的文件,它将被替换。否则,要么“原样”要么完全删除——取决于nullglob
。
您可以轻松地显示、设置 (-s
) 或取消设置 (-u
) 当前 bash 的 nullglob
选项的状态:
sh$ shopt nullglob
nullglob on
sh$ shopt -u nullglob
sh$ shopt nullglob
nullglob off
sh$ shopt -s nullglob
sh$ shopt nullglob
nullglob on
【讨论】:
【参考方案5】:如果您想从 grep 中排除某些文件,您应该使用 -l
选项。
grep -l --exclude=*.cmd ckim * -r
【讨论】:
以上是关于grep 排除文件名模式的主要内容,如果未能解决你的问题,请参考以下文章