Какой самый быстрый способ переместить миллион изображений из одного каталога в другой в Linux?
У меня есть миллион изображений, занимающих 30 ГБ дискового пространства, которые необходимо переместить из одного локального каталога в другой локальный каталог.
Какой самый эффективный способ сделать это? С помощью mv
? С помощью cp
? С помощью rsync
? Что-то другое?
Мне нужно принять это:
/path/to/old-img-dir/*
00000000.jpg
--------.jpg ## nearly 1M of them! ##
ZZZZZZZZ.jpg
и переместить их сюда:
/path/to/new/img/dir/
9 ответов
rsync
было бы плохим выбором, потому что он выполняет большую часть клиент-серверной работы, которая учитывает как локальные, так и удаленные системы.
mv
это, наверное, лучший выбор. Если возможно, вы должны попробовать mv directory_old directory_new
скорее, чем mv directory_old/* directory_new/
, Таким образом, вы перемещаете одну вещь вместо миллиона вещей.
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
, - Перемещение всего каталога, конечно, происходит намного быстрее, поскольку оно происходит в постоянное время независимо от количества файлов, содержащихся в нем, но:
- исходный каталог исчезнет на долю времени, и это может создать вам проблемы;
- если процесс использует текущий каталог в качестве выходного каталога (в отличие от всегда ссылающегося на полный путь из неподвижного местоположения), вам придется перезапустить его. (как вы делаете с ротацией журнала).
Кстати, я спрашивал себя, действительно ли мне нужно перемещать такое большое количество файлов одновременно. Пакетная обработка переоценена. Я стараюсь не накапливать огромное количество работы, если могу обрабатывать вещи в тот момент, когда они генерируются.
Если две директории находятся в одной файловой системе, используйте mv
на КАТАЛОГ, а не на содержимое каталога.
Если они находятся в двух разных файловых системах, используйте rsync:
rsync -av /source/directory/ /destination
Обратите внимание на трейлинг /
на источнике. Это означает, что он будет копировать СОДЕРЖАНИЕ каталога, а не сам каталог. Если вы оставите /
выключено, он все равно будет копировать файлы, но они будут находиться в каталоге с именем /destination/directory
, С / файлы просто будут в /destination
rsync
сохранит право собственности на файл, если вы запустите его от имени пользователя root или если файлы принадлежат вам. Это также будет поддерживать mtime
каждого отдельного файла.
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 использует различные процессы для чтения и записи, а также несколько шагов для одновременной работы с несколькими файлами. Даже на одном процессоре многопоточные приложения работают быстрее.
Так как directory_old и directory_new находятся в одной файловой системе, вы можете использовать cp -l
вместо mv
как вариант. cp -l
создаст жесткие ссылки на оригинальные файлы. Когда вы закончили с 'move' и удовлетворены результатом, вы можете удалить эти файлы из directory_old. с точки зрения скорости он будет таким же, как "mv", когда вы сначала создаете ссылки, а затем удаляете исходные. Но этот подход позволит вам начать с самого начала, если это имеет смысл
Характер места назначения будет определять наиболее эффективный способ решения этой задачи. Давайте предположим, что вы находитесь в локальной системе, ваш PWD
является /
прямо сейчас. а также /a
содержит миллионы изображений. Наша задача - переместить все изображения в /b
, сохраняя при этом всю структуру подкаталогов. Давайте также предположим, /a
а также /b
являются точками монтирования для двух разных разделов, каждый на локально подключенном диске. Мы хотели бы сделать эту задачу с брезентом. Это может занять некоторое время, поэтому убедитесь, что вы используете screen
, tmux
или вы выполняете это как фоновый процесс.
tar -C /a -cf . | tar -C /b -xf -
Это скопировало бы все файлы и каталоги в /a
в /b
, так что теперь вам нужно будет навести порядок /a
как только вы подтвердите это завершено без ошибок.
Чтобы скопировать как минимум ~10 тыс. Файлов (без каталогов), cp пожаловался:
невозможно выполнить /bin/cp: список аргументов слишком длинный
Лучший вариант - Rsync:
rsync исходная цель
И это было сделано очень быстро!
Если у вас есть свободное место, заархивируйте их в один файл.tar (без сжатия быстрее), а затем переместите этот файл и разархивируйте его.
Это зависит (тм). Если ваша файловая система копируется при записи, то копируйте (cp
или же rsync
например) должен быть сопоставим с ходом. Но для наиболее распространенных случаев переместить (mv
) будет самым быстрым, поскольку он может просто переключаться между фрагментами данных, которые описывают, где находится файл (примечание: это чрезмерно упрощено).
Итак, на вашей обычной установке Linux я бы пошел на mv
,
РЕДАКТИРОВАТЬ: @ Фредерик Хамиди имеет хорошее замечание в комментариях: это верно только в том случае, если они оба находятся в одной файловой системе и на диске. В противном случае данные будут скопированы в любом случае.