我正在使用一个简单的脚本来创建一些目录。按名称查找一些特定文件,然后将它们移动到我创建的目录中。我正在使用的代码如下:
mkdir ./3DBGB_run
mkdir ./run_optimization
mkdir ./run_optimization/project_mesh
mkdir ./run_optimization/CFD_optimized
find . -name '*.template' -exec mv -i {} ./3DBGB_run \;
find . -name '3dbgbinput.*.dat' -exec mv -i {} ./3DBGB_run \;
find . -name 'controlinputs.*.dat' -exec mv -i {} ./3DBGB_run \;
find . -name '*.iec' -exec mv -i {} ./run_optimization/project_mesh \;
find . -name '*.trb' -exec mv -i {} ./run_optimization/project_mesh \;
find . -name '*.py' -exec mv -i {} ./run_optimization \;**
代码运行并将文件移动到所需的目录,但随后它还会为每个文件显示一条错误消息“无法移动文件,因为它是同一文件”
答案1
您应该避免在目标目录中搜索。所以你可以添加! -path $TARGET_DIR
,例如:
find . -name '*.template' ! -path "*3DBGB_run/*" -exec mv -it ./3DBGB_run {} \+
答案2
find
会两次查找您的文件:在它们开始的位置以及您将它们移动到的位置。这意味着它最终会运行:
mv -i 3DBGB_run/x.template 3DBGB_run/x.template
并产生您看到的错误。
find
看到文件“实时”运行 - 它不会提前构建列表,然后对列表中的所有内容运行命令。它查看文件和目录的顺序是未定义的(它可能来自文件系统),因此在将其移动到的目录之前检查的每个文件都会发生这种情况。
因为find
不知道你在做什么-exec
,所以无法弥补。您可以对此做几件事:
- 从搜索空间中排除目录:
find . -name '*.template' -path "./3DBGB_run" -prune -o -exec mv -i {} ./3DBGB_run \;
.该-path
部分与您要将内容移入的目录相匹配,并且-prune
然后从递归中排除整棵树。-o
导致命令的其余部分(您原来的-exec
)在其余时间运行。该命令永远不会对目录内的文件运行。 (这是手册中的明确示例GNUfind
) 在搬家之前建立清单。在某些情况下这可能会更好,但如果您的文件名有空格或其他
IFS
角色的话,效果就不太好。如果这不适用,类似:files=$(find . -name '*.template') mv "${files[@]}" 3DBGB_run
也会起作用。
当您使用 时,以代替find -exec
结束命令将使运行最少数量的命令,在每次执行中收集多个参数,这样效率更高。有时这对特定命令不起作用,但在这里就可以了。如果这是一个一次性命令,那并不重要,但如果您经常运行它,那么保存进程将节省时间。+
;
find