поместить тысячи файлов в папки, названные определенным образом

поместить тысячи файлов в папки, названные определенным образом

У меня есть папка с именем test, в которой находятся только файлы jpeg. Тысячи файлов. Мне нужно поместить эти тысячи файлов с именами типа 1.jpg, 2.jpg... 345623.jpg в подпапки с именами типа 001000, 002000, каждая из которых будет содержать 1000 файлов. Поэтому мне нужно переместить все файлы jpg из папки test в подпапки, содержащие по 1000 файлов jpg, наиболее эффективным способом.

На данный момент у меня есть следующее:

i=1;while read l;do mkdir $i;mv $l $((i++));done< <(ls|xargs -n1000)

решение1

find . -type f \
| split -l 1000 -a 3 --numeric-suffixes=1 \
  --filter='target="${FILE}000"; mkdir "$target" && xargs -d "\n" mv -t "$target"' \
  - ''

Объяснение:

  • find . -type fнаходит файлы (также в подкаталогах, но я полагаю, что в вашем случае подкаталогов пока нет).
  • split -l 1000 -a 3 --numeric-suffixes=1 ... - ''считывает данные со своего stdin ( -) и разбивает данные на порции, каждая из которых имеет длину 1000 строк ( -l 1000). Каждой порции соответствует «имя», состоящее из пустого префикса ( '') и числового суффикса, начинающегося с 1 ( --numeric-suffixes=1) и имеющего длину 3 ( -a 3). Фактически на данный момент имена имеют вид 001, 002и так далее.
  • --filter=...запускает указанную команду отдельно для каждого фрагмента, соответствующее имя доступно как $FILE. Команда для запуска -

    target="${FILE}000"; mkdir "$target" && xargs -d "\n" mv -t "$target"
    
    • target="${FILE}000"преобразует имя, например 001или 002в желаемое имя будущего каталога ( 001000или 002000и т.п.), и сохраняет его в targetпеременной.
    • mkdir "$target"создает новый каталог с желаемым именем.
    • xargs -d "\n" ...считывает весь фрагмент (1000 путей к файлам или меньше в последнем фрагменте) и использует каждую целую строку (в качестве разделителя используется новая строка: -d "\n") в качестве аргумента для следующей команды.
      • mv -t "$target"перемещает объекты (переданные xargs) во вновь созданный каталог.

Примечания:

  • Команда не заботится об именах файлов. 345623.jpgне обязательно попадет в 346000/. Возможные причины:
    • findне сортирует; но даже если вы поместите sort -nмежду findи split, это может быть...
    • имеются пробелы в нумерации. splitв любом случае потребуется 1000 записей (если это не последний фрагмент; если так, то 1000 или меньше).
  • mkdir ... && xargs ...не запустится xargsв случае mkdirсбоя (будьте осторожны с существующими каталогами).
  • Используйте cp -l -t "$target"вместо mv -t "$target"для создания жестких ссылок в каталогах, оставляя уже существующие записи в текущем каталоге нетронутыми. Таким образом, если что-то пойдет не так, просто rm -rкаталоги и начните заново. С mv, если задача будет прервана, вы в конечном итоге переместите некоторые файлы, а некоторые нет; это может быть беспорядок.
  • Я думаю, -a 3что не пропустит вас 999( 999000после добавления конечных нулей). Если splitнужно создать больше фрагментов, он даст сбой в середине своей работы. По этой причине убедитесь, 999что этого достаточно, прежде чем запускать команду.
  • Имена с символами новой строки нарушат работу кода (в целом имена файлов выглядят нормально).

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