Как скопировать/заархивировать файлы из папки с огромным количеством файлов?

Как скопировать/заархивировать файлы из папки с огромным количеством файлов?

Итак, я совершил небольшую глупую ошибку. В процессе сбора данных из источника я слил все в корень моего внешнего диска, на котором сейчас около 600 тыс. файлов (всего 23 гига). Вот несколько вариантов, которые я хотел бы сделать:

  1. Переместить определенное количество файлов с диска на мой жесткий диск.
  2. Создайте подпапки (по 1000 файлов в каждой) и распределите файлы между ними.
  3. Заархивируйте все или какую-то его часть (скажем, 50 000 файлов) и перенесите их на мой диск.

Но что бы я ни пытался сделать, кажется, что это занимает вечность. Может ли кто-нибудь помочь мне с оптимальным/наиболее эффективным способом сделать что-либо из этого? Спасибо.

решение1

Следующий код создаст подкаталог с именем new, а затем 50 пронумерованных подкаталогов с newименами new/01.. new/50Затем он переместит максимум 1000 файлов из текущего каталога в каждый из каталогов new/*.

ПРИМЕЧАНИЕ 1: Это не сработает, если какой-либо изимена файлов\nсодержат в себе символы новой строки ( ).

ПРИМЕЧАНИЕ 2: для этого требуются GNU xargsи GNU mv. Вы используете Linux, поэтому они стандартны.

Вы можете изменить номера (50 и 1000) и базовый каталог в соответствии со своими потребностями.

#! /bin/sh

BASEDIR='new'
SUBDIRS=50
FILECOUNT=1000

mkdir -p "$BASEDIR"

for i in $(seq -w 1 "$SUBDIRS") ; do
   mkdir -p "$BASEDIR/$i"

   # move maximum of $FILECOUNT files to new/$i
   find . -maxdepth 1 -type f | head -n "$FILECOUNT" | xargs -d'\n' mv -t "$BASEDIR/$i"
done

Если все файлы, которые вы хотите переместить, соответствуют определенному шаблону, то вы можете использовать поиск -nameили -regexпараметры, чтобы выбрать их. Добавьте параметры сразу после -type f. Например, если вы хотите переместить только .txtфайлы:

find . -maxdepth 1 -type f -name '*.txt' | head -n "$FILECOUNT" | xargs -d'\n' mv -t "$BASEDIR/$i"

Не-GNU версия не может использовать mv -t. она также не может использовать xargs -dопцию , но вы можете использовать ее tr '\n' '\0'для преобразования символов новой строки в символы NUL для передачи в - опять же, это справляется с любым файлом, в имени xargs -0rкоторого нет . является не-POSIX, расширением FreeBSD для , вы можете безопасно удалить эту опцию, но операция будет выполняться намного медленнее.\n-R -1xargsmv

#! /bin/sh

BASEDIR='new'
SUBDIRS=50
FILECOUNT=1000

mkdir -p "$BASEDIR"

for i in $(seq -w 1 "$SUBDIRS") ; do
   mkdir -p "$BASEDIR/$i"

   # move maximum of $FILECOUNT files to new/$i
   find . -maxdepth 1 -type f | head -n "$FILECOUNT" | tr '\n' '\0' | xargs -0r -R -1 -I % mv % "$BASEDIR/$i"
done

Связанный контент