您最初尝试的麻烦:
find www/*.html -type f -exec sh -c "echo $(basename {})" ;是
$(basename{})代码在执行find命令之前执行一次。单曲的输出
basename是
{}因为它是{}文件名的基本名称。因此,由find执行的命令是:sh -c "echo {}"为找到的每个文件,但
find实际上每次都替换原始的(未修改的)文件名,因为
{}字符出现在要执行的字符串中。如果您希望它起作用,则可以使用单引号而不是双引号:
find www/*.html -type f -exec sh -c 'echo $(basename {})' ;但是,
echo将标准输出重复到标准
basename输出无论如何都是没有意义的:
find www/*.html -type f -exec sh -c 'basename {}' ;当然,我们可以进一步减少到:
find www/*.html -type f -exec basename {} ;您还能在这里解释单引号和双引号之间的区别吗?
这是常规的shell行为。让我们采取一个略有不同的命令(但仅略微-
文件名可以在
www目录下的任何位置,而不仅仅是向下一级),然后查看命令的单引号(SQ)和双引号(DQ)版本。命令:
find www -name '*.html' -type f -exec sh -c "echo $(basename {})" ; # DQfind www -name '*.html' -type f -exec sh -c 'echo $(basename {})' ; # SQ单引号将直接包含在命令中的材料传递给命令。因此,在SQ命令行中,启动的shell
find删除了引号,该
find命令将其
$9参数视为:
echo $(basename {})因为外壳会删除引号。相比之下,双引号中的材料由外壳处理。因此,在DQ命令行外壳(即发射
find-而不是一个推出 的
find),看到
$(basename {})串并执行它的一部分,取回{},所以它传递到字符串find作为它的
$9参数是:
echo {}现在,什么时候
find执行
-exec操作,在两种情况下都将其替换为
{}刚找到的文件名(出于论证目的www/pics/index.html)。因此,您将执行两个不同的命令:
sh -c 'echo $(basename www/pics/index.html)' # SQsh -c "echo www/pics/index.html" # DQ
那里有一个(轻微的)符号作弊-这些是您在shell中键入的等效命令。的
$2,实际上是启动了壳中有在任何情况下,没有引号-启动的外壳没有看到任何报价。
如您所见,DQ命令只是回显文件名。SQ命令运行该
basename命令并捕获其输出,然后回显捕获的输出。一点简化主义者的思想表明,DQ命令可以写为
-exec,SQ命令可以写为
-execbasename {} ;。如果您使用的是GNU
find,则它支持该
-printf操作,随后可以执行格式指令,从而
basename无需运行。但是,这仅在GNU中可用
find;此处的其余讨论适用于
find您可能遇到的任何版本。



