在 find 命令中使用“单引号”与不使用“单引号”有什么区别

在 find 命令中使用“单引号”与不使用“单引号”有什么区别
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

为了补充其他答案,zshfish(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'

相关内容