我只能访问busybox。
我有一个文件夹,如下所示:
prueba/$: ls
./uno
./dos
./tres
每两个子目录(uno,dos)都有很多文件(名称中带有空格和非 ASCII 字符),我想将它们移到另一个子目录(tres)。
所以我这样做了(转义字符只是因为,确保在复制和使用 yes 时不做冗余只是为了替换目录 [tres] 中已经存在的任何文件我之前遇到过 mv -f 的问题):
prueba/$: busybox find . -type f -not \( -path . -o -path ./tres \) -exec sh -c ' yes | mv "$1" ./tres ' sh {} \+
但它只移动它找到的第一个文件,然后退出。
但是如果我运行:
prueba/$: busybox find . -type f -not \( -path . -o -path ./tres \) -exec sh -c ' yes | mv "$1" ./tres ' sh {} \;
我得到了我的预期。所有文件都从子目录“uno”和“dos”移动到子目录“tres”。
;
[隐式循环]和+
[隐式批处理]到位时激活的内部机制是什么?
第一个命令行(带有 的命令行+
)有什么问题?
以下是不可能的:
mv -f ./uno/* ./dos/* ./tres/
我正在做一些自动化的工作,这将需要我只运行一个单线并完成这项工作。另外,这是一个无聊的解决方案。
编辑:
背后的原因find . -exec sh -c 'CMD "$1"' sh {} \;
将其更改为:
您的代码存在的问题:
find . -not -path ./tres
不排除./tres
,但不排除./tres/any-file-in-it
-exec sh 'mv "$1" tres' sh {} +
调用sh
尽可能多的文件作为参数,但您只移动第一个 ($1
)。将所有"$@"
位置参数扩展为单独的参数,就像您编写了."$1" "$2" "$3" ... "$last"
!
作为标准替代非标准-not
+
不是任何 shell 中的特殊字符。它不需要被引用。-f
选项,mv
因此您不需要yes
. 如果您仍然想使用yes
,您可以这样做yes | find ... -exec sh -c 'exec mv ...
, assh
并将mv
继承's stdin 并从那里find
读取s 。y
mv
GNU coreutils 和最新版本的实现busybox
,您可以sh
使用find ... -exec mv -ft tres {} +
.如果您想从任何目录(递归)移动文件,除了
./tres
当前目录中的文件和排除文件之外,您需要:上面的
-prune
内容告诉find
不要在 内部查找文件./tres
,而对于其他文件,-path './*/*'
(结合LC_ALL=C
so匹配任何字节字符串,而不仅仅是字符)限制为路径在前导之后*
至少包含一个的文件,因此不包括当前目录。/
./
与
zsh
:但请注意,如果当前目录中存在指向目录的符号链接,它们将被跟踪。如果达到系统对参数的数量和大小的限制,它也可能会失败(请参阅
zargs
解决方法)。与 相反
find
,zsh
glob 确实对文件列表进行排序,因此如果有多个具有相同名称的文件,那么最终./tres
将是哪个文件将更具确定性(这将是其路径最后排序的文件,但要注意顺序排uno
在后面dos
是词汇¹;所有其他的都将丢失)¹您可以添加
n
glob 限定符以获得数字顺序,但这仅适用于数字序列(例如,dir2
之前出现),仍然会在之后排序)dir10
uno
dos