的含义是什么?登录以下命令?
find /foo/path -name \?
答案1
?
是一个特殊字符模式匹配,匹配任何单个字符。
所以该命令的意思是查找/foo/path
其子目录中的所有文件和目录,其名称恰好是一个字符长。
用于\?
阻止您的 shell 执行文件名生成。您可以使用其他报价机制:
find /foo/path -name '?'
或者:
find /foo/path -name "?"
请注意,?
在文件名扩展模式永远不会匹配,并且由于斜杠的原因,/
给予 的模式也将在计算时被忽略-name
基本名称()文件的(A基本名称是路径名中的最终文件名或唯一文件名。还有一个文件名,在路径名上下文中,后面可以跟斜杠):
$ mkdir a b
$ find a/ b/ -name a -o -name b\?
a/
仅输出a/
。
唯一的例外是/
and//
在实现中,其中//
does not 引用/
:
$ find / ! -path / -prune -o -name \? -print
/
(POSIX 定义对于 的基本名称有点不清楚/
,//
并且///+
)
或者在 busybox 中找到:
$ busybox find a/ b/ -name a -o -name b\?
b/
如果您尝试使用/
给定的模式-name
,则行为会根据实现的不同而有所不同。
BSD find 和 heirloom find 将表达式视为 false,不输出任何内容:
$ find /tmp -name /tmp
$ echo "$?"
0
GNU find 会给出警告消息:
$ find /tmp -name /tmp
find: warning: Unix filenames usually don't contain slashes (though pathnames do).
That means that '-name ‘/tmp’' will probably evaluate to false
all the time on this system. You might find the '-wholename' test more useful,
or perhaps '-samefile'. Alternatively, if you are using GNU grep,
you could use 'find ... -print0 | grep -FzZ ‘/tmp’'.
它的返回码是0。
答案2
这?
是称为的机制的一部分shell 中的“路径名扩展”。
通俗地说,shell 机制称为“globing”。基本的 glob 仅使用三个字符:*
?
并[
构建“模式”。
星号的*
意思是:
- 任意数量的任意字符(任意字符串)。
问号(?
)表示:
- 任意角色一度。
方括号定义一个字符列表[ ]
,其含义是:
- 只有列表中的字符才算一次。可能存在否定列表。
那些在命令 find 中以类似的方式使用字符。在查找中,它们被称为“模式”。
这意味着有两个实体使用相同的字符来执行相同的任务(全局)。必须告诉人们忽略这些字符。告诉 shell 避免解释特殊字符的常用方法是“引用它们”。使用“单引号”、“双引号”或反斜杠:
'?'
"?"
\?
find
这就是为什么引用“模式”的原因:
find /path/foo -name \?
该行的意思是:
列出从该目录开始/path/foo
名称只有一个字符宽的所有文件和目录。
关于 /
注意 ?在 find 的模式扩展中可能会匹配/
.
find 中的Apattern
可以匹配/
POSIX 在 find 命令的操作数部分中指定的a:
-path pattern 如果当前路径名使用模式匹配表示法中描述的模式匹配表示法与模式匹配,则主值应评估为 true。用于文件名扩展的模式中的附加规则不适用,因为这是匹配操作,而不是扩展。
再次强调:文件名扩展(如在 shell 中)的附加规则...不适用,因为这是匹配操作,而不是扩展。
为了证明这是真的:
$ mkdir test; cd test
$ mkdir -p a/b/c/d
$ find a -path 'a?b'
a/b
$ find . -path './a?b?c?d'
./a/b/c/d
当然,-name
find的选项会匹配基本名称一个文件的。根据定义,不可能有 a,/
因为不可能/
在基本名称中匹配 a。