Копировать все изображения в каталоге в подкаталоги партиями по 30

Все мои изображения находятся в одной папке, их размер превышает 1,6К. Я хочу сделать пакет из 30 изображений из папки и скопировать этот пакет в соответствующую отдельную папку. Имена этих папок могут быть любыми, например папка1 , папка2 , fodler3 и т. Д.

Я понятия не имею, как подойти к проблеме . Я подумал о написании скрипта Python для копирования файлов один за другим и, как только счет достигнет 30, сменить папку. Но я подумал, что, может быть, вы лучше понимаете, как это сделать с помощью Bash.

2
задан 19 December 2020 в 22:58

3 ответа

Вы можете использовать этот сценарий Bash:

#!/bin/bash
from="/path/to/parent"       # <--- replace this
to="/path/to/target"         # <--- replace this
i=1

until [ "$(ls -A "$from")" = "" ]; do
    mkdir "$to/folder$i"
    files=("$from"/*)
    for f in "${files[@]:0:30}"; do
        mv "$f" "$to/folder$i"
    done
    i=$((i + 1))
done

В приведенном выше сценарии замените путь к переменной из на абсолютный путь к каталогу, содержащему ваши изображения и путь к переменной от до с абсолютным путем к каталогу, в который вы хотите переместить изображения. Пакеты из 30 изображений будут перемещены в каталоги с именем folder1 , папка2 , папка 3 и т. Д.

Сохраните сценарий как batch_move.sh (или любое другое имя по вашему желанию) и сделайте его исполняемым, запустив:

chmod u+x /path/to/batch_move.sh

Затем вы можете запустить сценарий как:

/path/to/batch_move.sh

Примечание: на всякий случай скопируйте часть ваших изображений в другой каталог и сначала протестируйте скрипт в нем. Если он работает должным образом, запустите его для всех ваших изображений.

1
ответ дан 3 January 2021 в 22:46

Вы можете использовать цикл for с приращением на 30.

#!/bin/bash

source=/opt/files/old
target=/opt/files/new

cd "$source" # && touch {000..300}

eval a=($( \
    ls --quoting-style=shell-escape) \
)
for ((b=0; b<${#a[@]}; b+=30)); do
    mkdir -p "$target/folder$((++c))" && mv -t "$_" "${a[@]:$b:30}"
done
1
ответ дан 3 January 2021 в 22:46

Используйте GNU parallel :

#!/bin/bash
mkdir_mv(){ target=$1; shift; mkdir "$target"; mv -t "$target" "$@"; }
export -f mkdir_mv
parallel -n 30 -j1 mkdir_mv "folder{#}" {} ::: *

Обычно mv не создает каталоги, мы сначала определяем функцию, которая тот. Нам нужно экспортировать функцию, чтобы она работала с параллельно

Вы запустите команду parallel из папки с вашими изображениями.

Пояснение :

  • -n 30 использовать 30 аргументов для каждого параллельного запуска
  • -j 1 запускать только 1 процесс параллельно (= делать не запускать параллельно)
  • {#} текущий номер прогона
  • {} 30 аргументов для каждого прогона.
  • ::: разделитель аргументов.
  • * Входные файлы.

параллельно могут быть установлены с:

sudo apt install parallel
4
ответ дан 3 January 2021 в 22:46

Другие вопросы по тегам:

Похожие вопросы: