Перераспределять файлы в несколько подкаталогов с максимальным размером - PullRequest
1 голос
/ 09 мая 2019

У меня большой каталог files_pdf, который содержит 110 000 pdf-документов. Каждый из этих документов имеет разный размер файла.

Я хотел бы перераспределить все эти документы в наборе подкаталогов, чтобы все подкаталоги имели примерно одинакового общего накопленного размера. Я не хочу разбивать файлы на несколько частей.

Я пробовал:

split -b 4000k myfile segment

Но в некоторых случаях это может сломать мой PDF.

1 Ответ

2 голосов
/ 09 мая 2019

Решение, основанное на алгоритме первичной подгонки бункерной упаковки, может быть следующим:

Создайте файл с именем bin_packing.awk:

function first_fit(v, file) {
    # find first bin that can accomodate the volume
    for (i=1; i<=n; ++i) {
        if (b[i] > v) {
            b[i] -= v
            bc[i]++
            cmd="mv "file" subdir_" i
            print cmd
            # system(cmd)
            return
        }
    }
    # no bin found, create new bin
    if (i > n) {
        b[++n] = c - v
        bc[n]++
        cmd="mkdir subdir_"n
        print cmd
        # system(cmd)
        cmd="mv "file" subdir_"n
        print cmd
        # system(cmd)
    }
    return
}
BEGIN{ if( (c+0) == 0) exit }
{ first_fit($1,$2) }
END { print "REPORT:"
    print "Created",n,"directories"
    for(i=1;i<=n;++i) print "- subdir_"i,":", c-b[i],"bytes",bc[i],"files"
}

и затем выполните строку:

$ find . -type f -iname '*pdf' -printf "%s %p\n"

Это создаст список файлов с размером файла в байтах перед ним.Что-то похожее на:

8 file_1
1 file_2
8 file_3
4 file_4
4 file_5
4 file_6
10 file_7
...

Теперь вы можете выполнить следующее:

$ find . -type f -iname '*pdf' -printf "%s %p\n" \
  | awk -v c=100000 -f bin_packing.awk

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

Это создаст вывод, например:

...
mv file_47 subdir_6
mv file_48 subdir_6
mv file_49 subdir_5
mv file_50 subdir_6
REPORT:
Created 6 directories
- subdir_1 : 49 bytes 12 files
- subdir_2 : 49 bytes 9 files
- subdir_3 : 49 bytes 8 files
- subdir_4 : 49 bytes 8 files
- subdir_5 : 48 bytes 8 files
- subdir_6 : 37 bytes 5 files

Если вам нравится то, что вы видите, вы можете удалить комментарии в bin_packing.awkscript.

note: это явно предполагает, что ваши имена файлов нормальные.Т.е. без забавных персонажей и без пробелов в них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...