Какой самый быстрый способ переместить миллион изображений из одного каталога в другой?

18322
Ryan

У меня есть миллион образов, 30 ГБ дискового пространства, которые нужно переместить из одного локального каталога в другой локальный каталог.

Какой будет самый эффективный способ? мв? ф? Rsync? Что-то другое? Подсказки?

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

Переместите их сюда:

/path/to/new/img/dir/ 
10
Я не думаю, что вы можете превзойти `mv` с точки зрения производительности, если и исходный, и целевой каталоги находятся в одной файловой системе. Frédéric Hamidi 12 лет назад 4

8 ответов на вопрос

21
Richard

rsync было бы плохим выбором, потому что он выполняет большую часть клиент-серверной работы, которая учитывает как локальные, так и удаленные системы.

mvэто, наверное, лучший выбор. Если возможно, вы должны попробовать, mv directory_old directory_newа не mv directory_old/* directory_new/. Таким образом, вы перемещаете одну вещь вместо миллиона вещей.

+1 за совет по перемещению каталогов вместо файлов. Ex Umbris 12 лет назад 5
Кроме того, расширение по шаблону, вероятно, сломает максимальные аргументы, поддерживаемые `mv`, если мы говорим о миллионах. slhck 12 лет назад 3
rsync прекрасно справляется с передачей на локальный носитель. Он вызывает такие вещи, как --whole-file (исключая реализацию алгоритма delta xfer), и предотвращает другие вещи, такие как --compression, которые не имеют смысла при локальной передаче. Если каталоги находятся в разных файловых системах, mv не обеспечит никакой производительности. Если они действительно находятся в одной файловой системе, то просто 'mv' каталоги, как сказали эти люди. UtahJarhead 12 лет назад 5
Если изображений много, использование подстановочного знака простой оболочки приведет к переполнению максимальной командной строки. Raúl Salinas-Monteagudo 7 лет назад 0
При перемещении между дисками все данные будут перемещаться. На том же диске `mv` просто обновляет информацию об узлах, поэтому` mv directory_old directory_new` работает быстрее, чем `mv directory_old / * directory_new` Anshul 6 лет назад 0
12
Raúl Salinas-Monteagudo
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Это не будет переполнять расширение аргумента.
  • Вы можете указать расширение файла, если хотите. (-название ...)
  • find -print0с xargs -0позволяет использовать пробелы в именах.
  • xargs -rне будет работать, mvесли нет чего-то для перемещения. ( mvбудет жаловаться, если исходные файлы не указаны).
  • Синтаксис mv -tпозволяет указать сначала место назначения, а затем исходные файлы, необходимые для xargs.
  • Перемещение всего каталога, конечно, происходит намного быстрее, поскольку оно происходит за постоянное время независимо от количества файлов, содержащихся в нем, но:
    • исходный каталог исчезнет на долю времени, и это может создать вам проблемы;
    • если процесс использует текущий каталог в качестве выходного каталога (в отличие от всегда ссылающегося на полный путь из неподвижного местоположения), вам придется перезапустить его. (как вы делаете с ротацией журнала ).

Кстати, я бы спросил себя, действительно ли мне нужно перемещать такое большое количество файлов одновременно. Пакетная обработка переоценена. Я стараюсь не накапливать огромное количество работы, если могу обрабатывать вещи в тот момент, когда они генерируются.

Это работает достаточно хорошо для перемещения файлов между файловыми системами на одном сервере. Достаточно хорошо, что я не стал искать решение в rsync. Конечно, это заняло час или два, но это работает. Стоит отметить, что если вы дадите имя каталога, вместо "." - обязательно используйте завершающую косую черту в команде find, иначе каталог будет воссоздан в месте назначения команды mv. Speeddymon 7 лет назад 0
4
UtahJarhead

Если два каталога находятся в одной и той же файловой системе, используйте mvкаталог DIRECTORY, а не содержимое каталога.

Если они находятся в двух разных файловых системах, используйте rsync:

rsync -av /source/directory/ /destination

Обратите внимание на трейлинг /на источнике. Это означает, что он будет копировать СОДЕРЖАНИЕ каталога, а не сам каталог. Если вы /выключите, он все равно будет копировать файлы, но они будут находиться в каталоге с именем /destination/directory. С / файлы просто будут в/destination

rsyncсохранит право собственности на файл, если вы запустите его от имени пользователя root или если файлы принадлежат вам. Он также будет поддерживать mtimeкаждого отдельного файла.

Для копирования большой папки с одного жесткого диска на другой жесткий диск, `rsync`, кажется, вращается вокруг` mv`. Спасибо за чаевые! leo-the-manic 11 лет назад 0
1
Serge

Так как directory_old и directory_new находятся в одной файловой системе, вы можете использовать ее cp -lвместо mvопции. cp -lсоздаст жесткие ссылки на оригинальные файлы. Когда вы закончили с 'move' и удовлетворены результатом, вы можете удалить эти файлы из directory_old. с точки зрения скорости он будет таким же, как «mv», так как вы сначала создаете ссылки, а затем удаляете исходные. Но этот подход позволит вам начать с самого начала, если это имеет смысл

0
carlpett

Это зависит (тм). Если ваша файловая система копируется при записи, то копирование ( cpили rsync, например) должно быть сравнимо с перемещением. Но для большинства распространенных случаев move ( mv) будет самым быстрым, поскольку он может просто переключаться между фрагментами данных, которые описывают, где находится файл (примечание: это слишком упрощено).

Итак, на вашей обычной установке Linux я бы пошел mv.

РЕДАКТИРОВАТЬ: @ Фредерик Хамиди имеет хорошее замечание в комментариях: это верно только в том случае, если они оба находятся в одной файловой системе и на диске. В противном случае данные будут скопированы в любом случае.

0
Nico

Чтобы скопировать как минимум ~ 10k файлов (без каталогов), cp пожаловался:

невозможно выполнить / bin / cp: список аргументов слишком длинный

Лучший вариант - Rsync:

rsync исходная цель

И это было сделано очень быстро!

0
endolith

Если у вас есть свободное место, заархивируйте их в один файл .tar (без сжатия быстрее), а затем переместите этот файл и разархивируйте его.

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

When you use 'cp' each file does a open-read-close-open-write-close. Tar uses different processes for reading and writing as well as multiple treads to operate on multiple files at once. Even on a single CPU box multithreaded apps are faster.

Хотя это может ответить на вопрос, было бы лучше ответить, если бы вы могли дать какое-то объяснение ** почему ** это так. DavidPostill 8 лет назад 2
Если они находятся на локальном компьютере, скорее всего, они находятся в одной файловой системе. Используя `tar c | tar x` вы получаете стоимость O (total_size) вместо O (file_count). Raúl Salinas-Monteagudo 7 лет назад 0