Автоматическое копирование папок до достижения определенного предела - PullRequest
2 голосов
/ 28 декабря 2008

Привет.

1 - допустим, у меня есть около 500 папок переменного размера общим размером 100 ГБ.

2 - Я хочу автоматически распределять эти папки в другие папки, пока не будет достигнут размер 700 МБ с наилучшей оптимизацией пространства.

Пример: в папке «CD - 01» я хочу, чтобы максимально возможное количество папок не превышало ограничение 700 МБ и т. Д. В «CD - 02», «CD - 03» .. .

Есть ли инструмент, позволяющий мне делать это "на лету", или мне придется самому его кодировать?

Спасибо

Ответы [ 4 ]

2 голосов
/ 29 декабря 2008

В конечном итоге вы запрашиваете решение проблемы с рюкзаком , которая входит в число во многих формах .

Простой подход был бы для следующего псевдокода, но это не даст оптимальные решения для всех входных данных (см. Статьи выше).

while (there are unallocated files) {
    create a new, empty directory
    set remaining space to 700,000,000
    while (the size of the smallest unallocated is at most (<=) the remaining space) {
        copy into the current the largest unallocated file with size at most the remaining space
        subtract that file's size from the remaining space
        remove that file from the set of unallocated files
    }
    burn the current directory
}

(Конечно, это предполагает, что ни один файл не будет иметь размер более 700 МБ. Если это возможно, обязательно удалите все такие файлы из нераспределенного списка, иначе приведенное выше приведет к бесконечному количеству пустых каталогов! ;-)

0 голосов
/ 28 декабря 2008

Есть инструменты, которые сделают это - подобно ответу франкодвайера, WinZip возьмет ваши 100 ГБ, разархивирует его и разделит на «куски» любого размера, то есть ~ 700 МБ

Вот страница функции разделения WinZip

0 голосов
/ 28 декабря 2008

Это очень наивное и плохо закодированное решение, но оно работает. Мой bash-fu не силен, но сценарий оболочки кажется лучшим способом решения этой проблемы

#!/bin/bash
dirnum=1
for i in *
    do
    if [ `du -b -s "$i" | cut -f 1` -gt 700000000 ]
        then
        echo "$i is too big for a single folder, skipping"
        continue
    fi
    if [ ! -d "CD_$dirnum" ]
        then
        echo "creating directory CD_$dirnum"
        mkdir "CD_$dirnum"
    fi
    echo "moving $i to CD_$dirnum"
    mv "$i" "CD_$dirnum"
    if [ `du -b -s "CD_$dirnum" | cut -f 1` -gt 700000000 ]
        then
        echo "CD_$dirnum is too big now"
        mv "CD_$dirnum/$i" .
        let "dirnum += 1"
        if [ ! -d "CD_$dirnum" ]
            then
            echo "creating directory CD_$dirnum"
            mkdir "CD_$dirnum"
        fi
        echo "moving $i to CD_$dirnum"
        mv "$i" "CD_$dirnum"
    fi
done
0 голосов
/ 28 декабря 2008

Если вы работаете в UNIX (включая Mac OSX), вы можете написать что-то вроде

tar cvzf allfolders.tgz ./allfolders
split allfolders.tgz -b 700m

Это создаст (сжатый) архив всех папок, а затем разделит его на куски размером 700 МБ. Однако вам нужно будет рекомбинировать все фрагменты, а затем снова извлечь их, используя tar, когда вы хотите восстановить исходный набор папок.

Если вы хотите сохранить их как отдельные папки ОС на компакт-диске, это довольно сложно (на самом деле я думаю, что это своего рода проблема с рюкзаком, которая является NP-трудной).

...