Каков наиболее эффективный способ перемещения большого количества файлов, находящихся в одном каталоге?

11

CentOS 5.x

Я прошу прощения, если это повторный вопрос. Я видел много похожих вопросов (относительно удаления файлов), но не совсем по тому же сценарию.

У меня есть каталог, содержащий сотни тысяч файлов (возможно, более миллиона), и в качестве краткосрочного решения другой проблемы мне нужно переместить эти файлы в другое место.

С целью обсуждения, скажем, эти файлы изначально находятся, /home/foo/bulk/и я хочу переместить их в/home/foo2/bulk2/

Если я пытаюсь, mv /home/foo/bulk/* /home/foo2/bulk2/ я получаю ошибку «слишком много аргументов».

Г-н Гугл говорит мне, что альтернативой массового удаления файлов будет запуск поиска. Что-то вроде: find . -name "*.pdf" -maxdepth 1 -print0 | xargs -0 rm

Это было бы хорошо, если бы я удалял материал, но в этом случае я хочу переместить файлы ... Если я наберу что-то вроде find . -name "*" -maxdepth 1 -print0 | xargs -0 mv /home/foo2/bulk2/bash, то жалуется на то, что файл не является каталогом.

Какую команду лучше использовать здесь для массового перемещения файлов из одного каталога в другой?

Майк Б
источник

Ответы:

16

Воспользовавшись GNU mv«S -tпараметр , чтобы указать целевую папку, вместо того , чтобы полагаться на последний аргумент:

find . -name "*" -maxdepth 1 -exec mv -t /home/foo2/bulk2 {} +

Если вы работали в системе без опции, вы могли бы использовать промежуточную оболочку для получения аргументов в правильном порядке ( find … -exec … +не поддерживает добавление дополнительных аргументов после списка файлов).

find . -name "*" -maxdepth 1 -exec sh -c 'mv "$@" "$0"' /home/foo2/bulk2 {} +
Жиль "ТАК - перестань быть злым"
источник
Вы можете использовать find ... -exec sh -c 'blah "$ @" blah' sh {} + "(" трюк с оболочкой ") для решения проблем, связанных с упорядочением аргументов. В findutils есть несколько примеров информация) документация; поиск по "sh -c".
Джеймс Янгман
5

Рассматривая mvродительский каталог вместо файлов:

mv /home/foo/bulk /home/foo2/bulk2 && mkdir /home/foo/bulk

(Но это может вызвать проблемы, если /home/foo/bulkдолжно существовать в каждый момент.)

Скот
источник
1
Я бы добавил к этому, на всякий случай, если ваш каталог назначения существует, переместите файлы в каталоге назначения в ваш исходный каталог (большой) и переименуйте каталог.
sbenitezb
Спасибо - отличное предложение. В этом случае каталог должен существовать в любой момент. Отличная идея, хотя.
Майк Б
Я должен признать, я не понимаю, что делает этот ответ. Почему mkdir? А что насчет этого режиссера, «существующего в каждый момент» или нет? Зачем это ускорять?
Моника Хеднек
Я знаю, что этому комментарию исполнился год, но последнему было пять лет, поэтому я подумал, что я могу также ответить ... Ваши первые два вопроса взаимосвязаны. Это mkdirпотому, что вся папка и все, что в ней находится, будут перемещены в другой каталог и больше не будут существовать в старом каталоге. Это гарантирует, что старый каталог все еще существует. Однако этого было бы недостаточно, если бы постоянно работала служба, которая зависела от первого всегда существующего каталога, потому что он перемещался, а затем создавался заново. Это не делает ничего быстрее, просто проще, предоставляя меньше аргументов.
Лукас
0

Просто для разнообразия, я люблю использовать cpio для некоторых подобных случаев.

find tmp |cpio -v  -p --make-directories --sparse tmp2
Артур Ульфельдт
источник
1
Если источник и место назначения находятся в одной файловой системе, такой подход может быть очень неэффективным (ненужное копирование). Также всегда лучше использовать -print0и -0варианты.
Пабук
0

С GNU mv:

find . -mindepth 1 -exec mv -t /tmp {} +

В таких системах, как OS X, которые не имеют, mv -tно имеют -print0и xargs -0:

find . -mindepth 1 -print0|xargs -0 -I, mv , /tmp

Или, если имена файлов не содержат пробелов, кавычек, обратной косой черты или новых строк (с OS X xargs) или кавычек, обратной косой черты или новых строк (с GNU xargs):

ls|xargs -I, mv , /tmp
LRI
источник
-3

В течение указанного времени попробуйте следующее:

find . -name "*" -type f -mtime +7 -exec mv -t /folder/to/transfer/files {} +
джинсовый
источник