我有以下文件/目录结构:
tsunami # find .
.
./dir1
./dir1/dirinner
./dir1/dirinner/innerfile
./logs
./messages
我正在尝试以递归方式查找文件并使用 find/exec 处理它们。
find 版本(由 busybox 提供)不允许在 exec 命令中多次使用发现的文件名,如上所述这里。因此,我使用了建议的解决方案之一。因此,我重写了以下内容:
find * -type f -exec echo {} +
更改为:
find * -type f -exec sh -c 'echo $0' {} +
但是新版本只能找到最里面的文件,而找不到其他任何东西。
以下是两者的输出:
tsunami # find * -type f -exec echo {} +
dir1/dirinner/innerfile logs messages
tsunami # find * -type f -exec sh -c 'echo $0' {} +
dir1/dirinner/innerfile
我该如何解决这个问题?我需要它来查找所有文件,而不仅仅是最里面的文件。
答案1
我认为echo
这只是你用来进行实验的豚鼠(唯一find . -type f
要做的是打印文件路径的工作)。
在我的回答中,为了简单起见,我使用了–find . …
而不是find * …
–。如果您有理由使用 shell 通配符,那么请继续。
您的问题是因为-exec … {} +
语法一次用多条路径替换了{}
;所以在获取许多参数-exec sh -c 'echo $0' {} +
时,但只引用一个,其余的仍未使用。sh
$0
使用"$@"
,这意味着"$1" "$2" "$3" …
。因为它会跳过,所以$0
您需要提供一个额外的(虚拟)参数。例如,sh
我使用sh
:
find . -type f -exec sh -c 'echo "$@"' sh {} +
还要注意,如果发现文件太多,一个命令行无法处理,则会运行多个sh
-s(因此多个-s)。echo
或者-exec … {} +
使用-exec … \;
:
find . -type f -exec sh -c 'echo "$0"' {} \;
sh
这将为每个文件单独运行,所以$0
就足够了。
另一个区别是:大多数find
实现要求{}
在 之前,但在的+
情况下可能在和之间。这意味着:\;
{}
-exec
\;
-exec foo {} bar +
是无效的;-exec foo {} bar \;
可以。
不过,对于您的特定情况来说,这种差异并不重要。