我一直在使用zsh globbing来运行命令,例如:
vim **/filename
vim *.html.erb
等等,但当我输入类似以下内容时:
find . -name *mobile*
我得到的响应是:
zsh: no matches found: *mobile*
为什么?
我一直在使用zsh globbing来运行命令,例如:
vim **/filename
vim *.html.erb
等等,但当我输入类似以下内容时:
find . -name *mobile*
我得到的响应是:
zsh: no matches found: *mobile*
为什么?
find . -name *mobile* # does not work
vs
find . -name '*mobile*' # works
区别在于Shell解析一行命令时所采取的步骤。通常,Shell在运行命令之前会扩展它发现的任何通配符。但是,单引号将参数标记为字面量,这意味着Shell在运行命令之前不对该参数执行通配符扩展。
为了演示差异,请假设您在具有以下文件的目录中:
$ tree
./
mobile.1
dir/
mobile.2
在第一种情况下,没有单引号,zsh 将进行以下处理:
mobile.1
find
,因此:find . -name mobile.1
find
命令只会查找文件名字面上为mobile.1的文件。
在第二种形式中,使用单引号,整个glob模式将被保留并传递给find
:
find . -name *mobile*
这意味着find将查找包含字符串“mobile”的任何文件名。
需要注意的重要事项是,zsh和find都支持相同的通配符语法;通过使用单引号,您可以诱使find
在此情况下处理通配符,而不是zsh。
find . -name '*mobile*'
目前我还没有确切的答案为什么会出现这种情况...而且文档中也没有明显的解释,如果你知道答案,请告诉我!
为了档案目的,这里是我对@Swiss上面回答进行的大规模编辑/重新格式化。每次我尝试编辑时,编辑队列都已经满了好几个小时,所以我想保存这份资料以备将来参考。希望这被认为是有建设性的。
要非常清楚,这是对另一个人的工作进行的修订。
find . -name *mobile* # does not work
vs
find . -name '*mobile*' # works
这个差异是由解析一行时shell所采取的步骤造成的。通常,shell在运行命令之前会扩展它发现的任何通配符。然而,单引号将参数标记为文字,这意味着shell在运行命令之前不会对该参数执行通配符扩展。
为了说明区别,假设您在一个目录中有以下文件:
$ tree
./
mobile.1
dir/
mobile.2
mobile.1
(因为这是当前目录中唯一匹配的文件名)find
,因此:find . -name mobile.1
因此,find
只会查找文件名为 mobile.1 的文件。
在第二种形式中,使用单引号,整个 glob 将被保留并传递给 find
:
find . -name *mobile*
这意味着find将寻找包含字符串“mobile”的任何文件名。
需要注意的重要事项是,zsh和find都支持相同的通配符语法;通过使用单引号,您可以诱使find在此情况下处理通配符,而不是zsh。