find ~/ -name *test.txt
find ~/ -name '*test.txt'
我需要构建一个示例,其中第一种形式失败,但第二种形式仍然有效。
答案1
引号可保护内容免受 shell 通配符扩展的影响。运行该命令(或者更简单,只需echo *test.txt
在一个包含footest.txt
文件的目录中运行,然后在一个没有任何文件结尾的目录中运行test.txt
,您就会看到区别。
$ ls
a b c d e
$ echo *test.txt
*test.txt
$ touch footest.txt
$ echo *test.txt
footest.txt
find 也会发生同样的事情。
$ set -x
$ find . -name *test.txt
+ find . -name footest.txt
./footest.txt
$ find . -name '*test.txt'
+ find . -name '*test.txt'
./footest.txt
$ touch bartest.txt
+ touch bartest.txt
$ find . -name *test.txt
+ find . -name bartest.txt footest.txt
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
$ find . -name '*test.txt'
+ find . -name '*test.txt'
./bartest.txt
./footest.txt
答案2
TL;博士版本
您将字符串文字传递给命令/程序,就像双引号一样,但不同之处在于单引号防止变量和通配符扩展,而双引号将它们扩展为字符串文字。
例子:
$ export MY_VAR=my_string
$ echo "$MY_VAR"
my_string
$ echo '$MY_VAR'
$MY_VAR
这同样适用于通配符
编辑:
像您问的例子在我看来是不可能的,因为第二个命令匹配的任何文字都将不可避免地与第一个命令中的通配符匹配。
答案3
为了补充其他答案,zsh
、fish
和(t)csh
在这里更有帮助,因为它们可以帮助您在错误成为问题之前显示错误:
*test.txt
如果当前目录下没有文件:
zsh$ find . -name *test.txt
zsh: no matches found: *test.txt
fish> find . -name *test.txt
fish: No matches for wildcard '*test.txt'.
find . -name *test.txt
^
tcsh> find . -name *test.txt
find: No match.
fish
并且zsh
明确表明这是正确的壳(not find
) 在这里抱怨, whiletcsh
的错误具有误导性。 (tcsh 仅报告No match
,但是如果全部命令行上的 glob 无法匹配。如果有些匹配而有些不匹配,则那些不匹配的将像在类似 Bourne 的 shell 中一样扩展到自身)。
使用bash
,您可以通过以下方式获得相同的行为:
$ shopt -s failglob
$ find . -name *test.txt
bash: no match: *test.txt
答案4
在第一种情况下,参数*test.txt
被视为命令本身的运算符find
,而使用引号时,参数*test.txt
将被视为 开关的参数find
。
如果当前目录中有多个具有.txt
扩展名的文本文件,则以下操作将失败,因为 find 将看不到参数*.txt
:
find . -name *.txt
而这将会成功:
find . -name '*.txt'