Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash grep不包括文件名模式_Bash_Shell_Grep - Fatal编程技术网

Bash grep不包括文件名模式

Bash grep不包括文件名模式,bash,shell,grep,Bash,Shell,Grep,我读过 但在我的世纪6.4,当我 grep --exclude=*.cmd ckim * -r 我在*.cmd文件中看到了许多灰色的行。 因此,排除选项似乎对我不起作用。 怎么了? 我当然可以做这样的事情 grep ckim \`find . -name \*.c -print\` 但是我想知道为什么grep不起作用。使用作为路径规范,而不是* grep -r --exclude \*.cmd ckim . 你也可以这样做 grep -rn ckim * | grep -v '\.cmd

我读过
但在我的世纪6.4,当我

grep --exclude=*.cmd ckim * -r
我在*.cmd文件中看到了许多灰色的行。
因此,排除选项似乎对我不起作用。
怎么了?
我当然可以做这样的事情

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

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

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

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

你也可以这样做

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

您可以引用以下模式:

grep -r --exclude="*.cmd"  "ckin" ./
PS.
/
是当前目录

我在*.cmd文件中看到了很多灰色的行。因此,排除选项似乎对我不起作用。

有一个名为
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
)搜索字符串
skim
,从
f.cmd
g.sh
sub
开始,但不包括与模式“*.cmd”匹配的任何文件

结果是:

# nullglob is unset
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
# nullglob is set
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
sub/h.cmd:ckim
但是如果在您的环境中设置了选项
nullglob
,则相同的命令将扩展为:

grep ckim f.cmd g.sh sub -r
请注意整个
--exclude=…
是如何消失的。因此,结果是:

# nullglob is unset
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
# 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

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

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

您需要包含
pattern
参数。在我的测试中,即使使用了
*
,该命令仍然有效。显式文件参数仍被筛选。@konsolebox:ACK with UbuntuI think
with
-r
更清晰,不会导致外壳扩展出现不必要的行为。@konsolebox:ACK with RHEL7这有不必要的行为,假设文件中的行有
something.cmd
即使文件名不包含
\.cmd
是,它也不会显示该行。它有一些不需要的行为。。。但在同一行上使用“.cmd”时发生ckim的可能性会小得多。除非OP设置了
nullglob
,否则不会产生显著差异
--exclude=*.cmd
不太可能与单个文件匹配,并将保持原样作为参数。这是正确的做法,但并没有给出解决方案。@konsolebox,我必须承认我对
nullglob
知之甚少,但
shopt
说它关闭了
,仍然有效。我遗漏了什么吗?它应该有用,但即使没有被引用,它仍然会有用。事实上,我的假设可能是错误的,您的代码可能确实能够帮助解决这个问题——不是因为您帮助它防止自身扩展到文件,而是因为您帮助它防止在启用
nullglob
时将其置为空。由于引用,防止了任何类型的路径名扩展。我不敢相信我真的忽略了那部分。