递归移动目录内容

递归移动目录内容

我想递归地将文件从一个文件夹(图片)移动到另一个文件夹(图片新)。

“图片”文件夹有很多子文件夹,因此我在跟进此处的帖子后使用了此命令。

Pictures 和 Picturesnew 都位于同一目录中。我只是想删除所有子文件夹并合并数据。

我从这些文件夹所在的目录运行以下命令。

find ./Pictures -type f -name "*.jpg" -print0 | 
xargs -0 -Imysongs mv -i mysongs ./Picturesnew

现在看起来应该出现的Picturesnew文件夹根本没有出现,因此我很困惑我的20000个JPG文件去了哪里。

答案1

你真的想要

mkdir Picturesnew
find Pictures -type f -iname "*.jpg" -exec mv -i {} + Picturesnew/

mv 不创建目录。

mv 的 -i 选项导致它在这样的管道中运行时无法工作。 (不过,从好的方面来说,它希望告诉 mv 不要践踏第一个重命名为 Picturesnew 的文件,而不是原来的文件。)

在我的解决方案中,我告诉 find 如果有用的话,在每个执行的 mv 实例中移动多个文件,以最大程度地减少出现错误的可能性,例如保留目标目录名称的尾部 / 以及没有使目标目录实际重命名文件,而不是生成所需的错误。它还具有允许 mv 实际上提示确认覆盖文件而不是简单地将下一个文件名视为“否”的优点。

答案2

我不知道为什么覆盖时没有确认,由于-i的参数,应该存在确认mv。但假设你没有使用它,并且考虑到Picturesnew操作后有一个 jpg 文件,正如你在问题下的评论中所述,那么 - 你覆盖了同一个文件 20000 次。

xargs -0 -Imysongs mv -i mysongs ./Picturesnew

这意味着对于每个参数都会执行此命令:

mv -i argument ./Picutesnew

由于没有目录,./Picturesnew该命令mv认为您的意思是它应该将文件移动到此处并重命名为./Picturesnew.它这样做了 20000 次。

管道执行完毕后,应该只剩./Picturesnew下一个文件。最后一个被移动的。以前的都没有了。

因此,这种形式更安全:

mv -i argument ./Picturesnew/

那是因为/最后消除了对Picturesnew应该是什么的混乱。

至于-i,您不会将其放入此管道中,因为它不起作用。它需要确认。

答案3

我认为您可以通过以下命令实现您的目标:

find Pictures -type f -print0 | xargs -0 mv -t Picturesnew

其中Pictures是源目录,Picturesnew是目标目录。

两者mv(和cp)都具有mv -t directory source...非常适合与 一起使用的格式xargs

但是此方法会将具有重复名称的文件保留在其原始位置(也许这还不错,因为您可以稍后查看它们并复制到目标),因为mv -t 使用输入重定向时将无法交互工作。这是因为xargs已经从重定向的标准输入(这是 的输出find)读取值,并且mv由 运行的xargs也尝试从相同的标准输入读取答案。因此,您不能以交互方式将 mv 与管道一起使用。

也许工作可以通过一些巧妙的输入句柄重新分配来解决,但让我们尝试更简单的方法:摆脱输出重定向。此外,我们不能-print0在命令替换中使用,因为它不允许 0 字节。我们需要使用for,迭代文件名使用换行符作为输入字段分隔符:

TMP=$IFS; 
IFS=$'\n'; 
for i in $(find Pictures -type f); do 
    mv -it ../Picturesnew $i; 
done; 
IFS=$TMP

(您可以将其复制为一行)。

在这种情况下,mv 不仅会询问您每个重复项,还会等待答案。

答案4

find Pictures -type f -iname "*.jpg" -print0 | xargs -0 -I {} mv -n "{}" Picturesnew/

这将是一个语法上更正确的解决方案,因此恢复您的备份并尝试一下。

相关内容