我想递归地将文件从一个文件夹(图片)移动到另一个文件夹(图片新)。
“图片”文件夹有很多子文件夹,因此我在跟进这里的帖子后使用了这个命令。
Pictures 和 Picturesnew 都在同一个目录中。我只是想摆脱所有子文件夹并合并数据。
我从这些文件夹所在的目录运行了以下命令。
find ./Pictures -type f -name "*.jpg" -print0 |
xargs -0 -Imysongs mv -i mysongs ./Picturesnew
现在似乎应该出现的 Picturesnew 文件夹根本没有出现,因此我对我的 20000 个 JPG 文件的去向感到困惑。
我不知道为什么在覆盖时没有确认,由于
-i
参数 to应该存在mv
。但是假设您没有使用它并且Picturesnew
在操作后有一个 jpg 文件,正如您在问题下的评论中所述,那么您将同一个文件覆盖了 20000 次。这意味着对于每个参数,该命令将被执行:
由于没有目录
./Picturesnew
,该命令mv
认为您的意思是它应该将文件移动到此处并重命名为./Picturesnew
. 它这样做了20000次。管道完成执行后,应该只剩下一个文件
./Picturesnew
。最后一个被搬走了。前面的都没有了。因此,这种形式更安全:
那是因为
/
最后消除了对Picturesnew
应该是什么的混淆。至于
-i
,你不会把它放在这个管道中,因为它不起作用。它需要确认。你真的想要
mv 不创建目录。
mv 的 -i 选项会导致它在这样的管道中运行时不起作用。(虽然,从好的方面来说,它希望告诉 mv 不要踩到第一个重命名为 Picturesnew 的文件,而不是原来的文件。)
在我的解决方案中,我告诉 find 为每个执行的 mv 实例移动多个文件(如果有用),以最大程度地减少错误(例如将目标目录名称的尾随/关闭并且没有创建目标目录)实际上会重命名一个文件,而不是生成所需的错误。它还具有允许 mv 实际提示确认是否覆盖文件的优点,而不是简单地将下一个文件名视为“否”。
将是一个语法更正确的解决方案,因此请恢复您的备份并尝试。
我认为您可以使用以下命令实现您的目标:
where
Pictures
是源目录,Picturesnew
是目标目录。mv
( 和)都具有适合与 . 一起使用的cp
格式。mv -t directory source...
xargs
但是这种方法会在其原始位置留下具有重复名称的文件(也许这还不错,因为您可以稍后查看它们并复制到目标位置),因为
mv -t
在使用输入重定向时不会以交互方式工作。这是因为xargs
已经从重定向的标准输入(即 的输出find
)中读取值,并且mv
由 运行的 也xargs
尝试从相同的标准输入中读取答案。因此,您不能以交互方式将 mv 与管道一起使用。也许工作可以通过一些巧妙的输入句柄重新分配来解决,但让我们尝试更简单的方法:摆脱输出重定向。我们也不能
-print0
在命令替换中使用,因为它不允许 0 字节。我们需要用 迭代文件名for
,使用换行符作为输入字段分隔符:(您可以将其复制为单行)。
在这种情况下, mv 不仅会询问您每个重复项,还会等待回答。