mv 命令错误“已存在文件”

mv 命令错误“已存在文件”

我正在使用一个简单的脚本来创建一些目录。按名称查找一些特定文件,然后将它们移动到我创建的目录中。我正在使用的代码如下:


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,所以无法弥补。您可以对此做几件事:

  1. 从搜索空间中排除目录:find . -name '*.template' -path "./3DBGB_run" -prune -o -exec mv -i {} ./3DBGB_run \;.该-path部分与您要将内容移入的目录相匹配,并且-prune然后从递归中排除整棵树。-o导致命令的其余部分(您原来的-exec)在其余时间运行。该命令永远不会对目录内的文件运行。 (这是手册中的明确示例GNUfind
  2. 在搬家之前建立清单。在某些情况下这可能会更好,但如果您的文件名有空格或其他IFS角色的话,效果就不太好。如果这不适用,类似:

    files=$(find . -name '*.template')
    mv "${files[@]}" 3DBGB_run
    

    也会起作用。


当您使用 时,以代替find -exec结束命令将使运行最少数量的命令,在每次执行中收集多个参数,这样效率更高。有时这对特定命令不起作用,但在这里就可以了。如果这是一个一次性命令,那并不重要,但如果您经常运行它,那么保存进程将节省时间。+;find

相关内容