在“find”中引用参数有何作用?

在“find”中引用参数有何作用?

查找 txt 文件时,我运行以下命令:

find . -name "*.txt" -print

这为我提供了当前目录下所有文本文件的列表。

但是,find . -name *.txt -print给我以下错误: find: paths must precede expression: mein.txt

这是普遍预期的行为吗?引号有什么区别?

答案1

在未加引号的令牌中,将由您的 shell 执行扩展,而不是您正在运行的命令。

这意味着,当您输入 时find . -name "*.txt" -print, find 会接收文字*.txt作为其参数之一,并使用此模式作为其选项的参数-name,该选项将与应用 之前找到的文件名称相匹配-print

另一方面,当您输入 时find . -name *.txt -print,shell 会传递扩展版本的*.txt来查找。可能有几种情况:

  1. *.txt当前目录中没有匹配的文件:find 接收一个文字*.txt(假设默认 bash 设置);

  2. *.txt当前目录下只有一个文件匹配;假设它是a.txt: find 接收此文件名,并匹配a.txt从当前目录开始的所有名为 find 的文件;

  3. 当前目录中有几个文件匹配*.txt(这似乎是您的情况):-name接收第一个文件作为其参数,其他文件是要查找的进一步路径参数,它抱怨没有在表达式之前给出所有路径。

这是预期的行为。


我们假设以下文件层次结构:

.
├── a.txt
├── b.txt
├── c.txt
└── foo
    ├── a.txt
    ├── b.txt
    └── c.txt

find 在每种情况下接收的实际参数可以通过将 find 调用替换为 来观察printf '%s\n',这将在其自己的行上打印每个扩展参数:

$ printf '%s\n' . -name "*.txt" -print
.
-name
*.txt
-print

$ printf '%s\n' . -name *.txt -print
.
-name
a.txt
b.txt
c.txt
-print

如您所见,鉴于现有文件,您发布的第二个调用等效于find . -name a.txt b.txt c.txt -print.

答案2

这是预期的行为 - 它被称为“shell globbing”。如果没有引号,*.txtshell 将扩展 ,将与该表达式匹配的整个文件列表传递给find命令。通过将其括在引号中,您可以告诉 shell 将文字字符串传递*.txtfind.您可以使用其他转义方法(例如find . -name \*.txt或 )来实现相同的保护find . -name '*.txt'

相关内容