在Linux中将一百万个图像从一个目录移动到另一个目录的最快方法是什么?


14

我有一百万个占用30GB磁盘空间的映像,这些映像需要从一个本地目录移动到另一个本地目录。

什么是最有效的方法?使用mv?使用cp?使用rsync?还有吗

我需要这些:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

并将它们移到这里:

/path/to/new/img/dir/

5
mv如果源目录和目标目录都位于同一文件系统中,那么我认为您不能在性能方面胜过。
弗雷德里克·哈米迪

Answers:


26

rsync 这将是一个糟糕的选择,因为它会执行许多客户端/服务器后台工作,这些工作需要考虑本地和远程系统。

mv可能是最好的选择。如果可能的话,您应该尝试mv directory_old directory_new而不是mv directory_old/* directory_new/。这样,您移动一件事而不是一百万件事。


6
+1为移动目录而不是文件的建议。
Ex Umbris

4
另外,mv如果我们谈论数百万,通配符扩展可能会破坏支持的最大参数。
slhck 2012年

6
rsync可以很好地处理本地存储介质上的传输。它强制执行--whole-file之类的操作(删除了增量xfer算法的实现),并阻止了诸如--compression之类的其他操作,这些操作在本地传输中毫无用处。如果目录位于不同的文件系统上,则“ mv”将不会提供任何性能。如果它们确实位于同一文件系统上,则只需像这些人所说的那样“ mv”目录。
犹他州黑海德2012年

如果有很多图像,使用简单的shell通配符将使最大命令行溢出。
劳尔·萨利纳斯-蒙塔古多

1
在磁盘之间移动仍将移动所有数据。在同一磁盘上,mv只需更新inode信息,即可mv directory_old directory_newmv directory_old/* directory_new
Anshul '18

14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • 这不会溢出参数扩展。
  • 如果需要,可以指定文件扩展名。(-名称 ...)
  • find -print0with xargs -0允许您在名称中使用空格。
  • xargs -rmv除非有要移动的东西,否则它将不会运行。(mv如果未提供源文件,则会抱怨)。
  • 该语法mv -t允许您先指定所需的目标,然后再指定源文件xargs
  • 当然,移动整个目录要快得多,因为不管它包含的文件数量如何,它都会在恒定的时间内发生,但是:
    • 源目录将消失一小段时间,这可能会给您带来麻烦;
    • 如果该进程将当前目录用作输出目录(与始终引用非移动位置的完整路径相反),则必须重新启动它。(就像您使用日志旋转一样)。

顺便说一句,我会问自己是否真的必须一次移动如此大量的文件。批处理被高估了。如果我能够在事物生成时立即对其进行处理,我就尽量不要积累大量的工作。


这足以在同一服务器上的文件系统之间移动文件。很好,我不必在rsync中寻找解决方案。当然花了一个或两个小时,但它确实有效。要注意的一件事是,如果要查找目录名称而不是“。”。-请确保在find命令中使用斜杠,否则将在mv命令的目标位置重新创建目录。
Speeddymon'7

7

如果两个目录位于同一文件系统上,则mv在DIRECTORY而不是目录的内容上使用。

如果它们位于两个不同的文件系统上,请使用rsync:

rsync -av /source/directory/ /destination

请注意/源上的尾随。这意味着它将复制目录的内容,而不是目录本身。如果/不选择,它仍将复制文件,但它们将位于名为的目录中/destination/directory。使用/,文件将位于/destination

rsync如果您以超级用户身份运行文件或文件归您所有,则将保持文件所有权。它还将维护mtime每个文件的。


2
要将大文件夹从一个硬盘驱动器复制到另一个硬盘驱动器,rsync似乎会绕圈转mv。谢谢你的提示!
leo-the-manic

2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

当您使用“ cp”时,每个文件都会执行open-read-close-open-write-close。Tar使用不同的读取和写入过程以及多个分支来一次处理多个文件。即使在单个CPU盒上,多线程应用程序也更快。


2
虽然这可以回答问题,但是如果您可以提供解释为什么会这样做会更好。
DavidPostill

1
如果它们在本地计算机中,则它们很可能位于同一文件系统中。通过使用,tar c | tar x您将获得O(total_size)而不是O(file_count)的成本。
劳尔·萨利纳斯-蒙塔古多

1

由于两个directory_old和directory_new都在同一个文件系统,你可以使用cp -l,而不是mv作为一个选项。cp -l将创建到原始文件的硬链接。当您完成“移动”并且对结果满意时,可以从directory_old中删除这些文件。在速度方面,当您首先创建链接然后删除原始链接时,它与“ mv”相同。但是如果可以的话,这种方法可以让您从头开始


0

这取决于(tm)。如果您的文件系统是写时复制,则复制(例如,cprsync)应与移动相当。但在大多数情况下,move(mv)将是最快的,因为它可以简单地切换描述文件放置位置的数据(注意:这过于简化了)。

因此,在您的平均Linux安装中,我会选择mv

编辑: @FrédéricHamidi在评论中有一个要点:仅当它们都在同一文件系统和磁盘上时,这才有效。否则,数据仍将被复制。


0

要复制至少约10k的文件(无目录),cp抱怨道:

无法执行/ bin / cp:参数列表过长

最好的选择是Rsync:

rsync源目标

而且很快就完成了!


0

如果有可用空间,则将它们归档到单个.tar文件中(没有压缩速度更快),然后将该文件移到上方并取消归档。


0

目的地的性质将决定执行此任务的最有效方法。让我们假设你是在本地系统上,你PWD/现在。并/a包含数百万个图像 我们的任务是将所有图像移到/b,同时保持所有子目录结构。我们还假设/a并且/b是两个不同分区的安装点,每个分区都在本地连接的磁盘上。我们想要用篷布完成此任务。这可能需要一些时间,所以一定要确保你使用screentmux或者在执行此作为后台进程。

tar -C /a -cf . | tar -C /b -xf -

这会将所有文件和目录复制/a到中/b,因此,/a一旦确认它没有错误,现在就需要清理。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.