Вопрос или проблема
У меня есть папка MAIN с примерно 1200 файлами, оканчивающимися на .bam. Я хочу скопировать эти файлы из MAIN в “/path/to/output/folder”, но в подпапки, содержащие по 50 .bam файлов каждая. Таким образом, я хочу разделить файлы из MAIN на подпапки, каждая из которых содержит 50 файлов. Подпапки не будут находиться в папке MAIN.
Я нашел решение на этой платформе, но не уверен, как его изменить, добавив путь вывода и сделав так, чтобы файлы копировались, а не перемещались.
i=0;
for f in *;
do
d=dir_$(printf %03d $((i/50+1)));
mkdir -p $d;
mv "$f" $d;
let i++;
done
Для простого исправления вы можете просто заменить mv
на cp
, чтобы переключиться с перемещения на копирование, затем добавьте префикс к $d
(например, "/path/to/$d"
).
Тем не менее, есть несколько предостережений относительно этого решения.
Я предполагаю, что вы, вероятно, работаете с “нормальными” именами файлов и папок, но поскольку это не всегда безопасное предположение, я рекомендую ознакомиться с Почему циклический обход выходных данных команды find является плохой практикой?, чтобы узнать надежные способы обхода имен файлов.
Вот одно решение, которое должно правильно обрабатывать произвольные имена файлов:
ORIGIN_DIR="/path/to/origin"
DESTINATION_PARENT_DIR="/path/to/destination"
SHARD_SIZE=50
FIND_BY_NAME="*.bam"
readarray -d '' -t ORIGIN_FILES < <(
find "$ORIGIN_DIR" -maxdepth 1 -type f -name "$FIND_BY_NAME" -print0
)
for index in "${!ORIGIN_FILES[@]}"; do
shard_suffix="$(printf %03d $(($index / $SHARD_SIZE + 1)))"
destination_dir="$DESTINATION_PARENT_DIR/part_$shard_suffix"
mkdir -p "$destination_dir"
cp "${ORIGIN_FILES[$index]}" "$destination_dir/"
done
Если вы хотите рекурсивно искать все пути в папке-источнике, а не просто работать с ее прямыми дочерними элементами, вы можете удалить аргумент -maxdepth 1
.
Ответ или решение
Копирование директории в подкаталоги на Linux: Подробное руководство
Если у вас есть директория с множеством файлов и вы хотите организовать эти файлы по подкаталогам с определённым ограничением на количество файлов в каждом подкаталоге, вы на правильном пути. В этой статье мы подробным образом рассмотрим, как скопировать файлы из директории MAIN
в подкаталог /path/to/output/folder
, размещая по 50 файлов в каждом подкаталоге.
Общий алгоритм
- Определение путей: Убедитесь, что вы правильно указали исходный и целевой каталоги.
- Сбор файлов: Используйте команду
find
, чтобы собрать все нужные файлы с расширением.bam
. - Копирование файлов в подкаталоги: Создайте подкаталоги и размещайте в них файлы в соответствии с заданным количеством.
Пример скрипта
Ниже представлен пример скрипта, который поможет вам в решении данной задачи. В этом скрипте используются современные средства Bash для работы с файлами, включая массивы и безопасное чтение имен файлов.
#!/bin/bash
# Определяем пути к исходной и целевой директориям
ORIGIN_DIR="/path/to/MAIN"
DESTINATION_PARENT_DIR="/path/to/output/folder"
SHARD_SIZE=50 # Количество файлов в подкаталоге
FIND_BY_NAME="*.bam" # Шаблон для поиска
# Читаем файлы в массив, учитывая специальные символы
readarray -d '' -t ORIGIN_FILES < <(
find "$ORIGIN_DIR" -maxdepth 1 -type f -name "$FIND_BY_NAME" -print0
)
# Проходим по каждому файлу и копируем его в соответствующий подкаталог
for index in "${!ORIGIN_FILES[@]}"; do
shard_suffix="$(printf %03d $((index / SHARD_SIZE + 1)))" # Счётчик для создания имени подкаталога
destination_dir="$DESTINATION_PARENT_DIR/part_$shard_suffix" # Имя подкаталога
mkdir -p "$destination_dir" # Создание подкаталога, если его нет
cp "${ORIGIN_FILES[$index]}" "$destination_dir/" # Копирование файла
done
Пояснение к скрипту
-
Настройка переменных:
ORIGIN_DIR
: Исходная директория, содержащая файлы.DESTINATION_PARENT_DIR
: Директория, куда будут скопированы подкаталоги.SHARD_SIZE
: Максимальное количество файлов в подкаталоге. Вы установили 50.FIND_BY_NAME
: Используется для фильтрации файлов по заданному шаблону.
-
Сбор файлов:
- Команда
find
ищет все файлы с расширением.bam
в указанной директории. Опция-print0
позволяет безопасно работать с файлами, содержащими пробелы или другие специальные символы.
- Команда
-
Копирование файлов:
- Цикл проходит по всем найденным файлам. В зависимости от индекса файла создаётся подкаталог с уникальным номером.
- Команда
mkdir -p
создаёт подкаталог, если он ещё не существует. - Команда
cp
копирует файлы в соответствующие подкаталоги.
Заключение
Данный подход позволяет организовать ваши файлы в удобном формате, с лёгким доступом к каждой группе из 50 файлов. Улучшенное управление путями и безопасность работы с именами файлов делают данный скрипт эффективным инструментом для любого администратора или разработчика.
Если у вас возникнут вопросы или потребуется дальнейшая помощь, не стесняйтесь уточнять!