帮助理解 Solaris 上的“查找”语法

帮助理解 Solaris 上的“查找”语法

考虑以下文件:

$ find findtest                     
findtest
findtest/test1
findtest/test1/start.ksh
findtest/test2
findtest/test2/start.ksh
findtest/test3
findtest/test3/start.ksh
findtest/test4
findtest/test4/start.ksh

{}我的问题是关于通话中的使用-exec。它的工作原理正如我在指定结果文件时所期望的那样:

$ find findtest -name test[1-4] -exec ls -d {} \;           
findtest/test1
findtest/test2
findtest/test3
findtest/test4

然而,在路径中使用时它似乎没有扩展:

$ find findtest -name test[1-4] -exec md5sum {}/start.ksh \;     
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory

如何使用find -type d -exec访问较低层次结构的文件?我知道我可以使用这样的循环,但我很好奇是否可以在一次调用for中完成它:find

$ for f in $(find findtest -name test[1-4]); do md5sum "$f"/start.ksh; done
d41d8cd98f00b204e9800998ecf8427e  findtest/test1/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test2/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test3/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test4/start.ksh

答案1

find 命令的 POSIX 标准仅要求用文件名替换独立的 {},并且仅替换第一个。使用{}/start.ksh会导致未指定的行为。

仅包含两个字符“{}”的参数应替换为聚合路径名集,每个路径名按照聚合顺序作为单独的参数传递给调用的实用程序。任何两个或多个路径名集合的大小均应受到限制,以便实用程序的执行不会导致超出系统的 {ARG_MAX} 限制。如果存在多个仅包含两个字符“{}”的参数,则行为未指定。

如果 utility_name 或参数字符串包含两个字符“{}”,而不仅仅是两个字符“{}”,则 find 是否替换这两个字符或不更改地使用该字符串是实现定义的。

使用 Solaris find 执行所需操作的一种方法是使用以下命令:

find findtest -name "test[1-4]" -exec sh -c 'md5sum $1/start.ksh' foo {} \;

更快的方法是:

find findtest -name "test[1-4]" -exec sh -c 'for i; do md5sum "$i/start.ksh"; done' foo {} + 

答案2

  1. 实际上,您的 shelltest[1-4]在调用之前正在扩展find。你需要逃避它'…'
  2. {}仅当它是一个单独的标记时才被视为模式

-exec其本身通常成本较高,建议与尾随一起使用+,或避免使用以利于喂食xargs

我知道我可以使用这样的 for 循环,但我很好奇是否可以在一个 find 调用中完成它:

find findtest -name 'test[1-4]' -print0 | xargs -0I{} -- md5sum '{}/start.ksh'md5sum高效运行 — 一次性给出所有文件名。

相关内容