3

问候。

1 - 假设我有大约 500 个大小可变的文件夹,总大小为 100 GB。

2 - 我想将这些文件夹自动分配到其他文件夹中,直到达到 700 MB 的大小并优化空间。

示例:在文件夹“CD--01”中,我希望在不超过 700 MB 限制的情况下拥有尽可能多的文件夹,依此类推,在“CD--02”、“CD--03”...

是否有一种工具可以让我“即时”执行此操作,还是我必须自己编写一个?

谢谢

4

5 回答 5

2

归根结底,您是在寻求解决背包问题的方法,该问题有多种形式

一个简单的方法是按照以下伪代码,但这不会为所有输入产生最佳解决方案(参见上面的文章)。

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
}

(当然,这假设单个文件的大小不会超过 700MB。如果可能,请务必从未分配列表中删除任何此类文件,否则上述将产生无限多的空目录!;-)

于 2008-12-28T21:09:14.060 回答
1

这是一个非常幼稚且编码不佳的解决方案,但它确实有效。我的 bash-fu 不强,但 shell 脚本似乎是解决这个问题的最佳方法。

#!/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
于 2008-12-28T02:14:37.097 回答
0

如果你在 UNIX (inc Mac OSX) 上,你可以编写类似的脚本

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

这将创建所有文件夹的(压缩)存档,然后将其拆分为 700M 大小的块。但是,当您想要重构原始文件夹集时,您需要重新组合所有部分,然后使用 tar 再次提取。

如果您想将它们作为单独的操作系统文件夹保存在 CD 上,那是相当困难的(实际上我认为这是一种背包问题,这是 NP 难题)。

于 2008-12-27T22:11:36.993 回答
0

有一些工具可以做到这一点 - 类似于 frankodwyer 的回答,WinZip会占用你的 100GB,将其压缩并分成你想要的任何大小的“块” - 即 ~700MB

这是WinZip 拆分功能的页面

于 2008-12-27T22:17:19.290 回答
0

我参加聚会有点晚了,但这是我解决问题的方法:

#!/usr/bin/env bash

sourcedir="$1"
destdir_prefix="./disk_"
destdir_suffix=""
mblimit=4100
# bytelimit=$(( mblimit * 1024 * 1024 )) # MB as measured by OS (MiB)
bytelimit=$(( mblimit * 1000 * 1000 )) # MB as measured by marketeers
disk=() # empty array
dir_size=0
find "${sourcedir}" -type f |
  while read file; do

    file_size="$( stat --printf="%s" "${file}" )"
    disk_number=0
    stored=false
    while [[ "${stored}" == "false" ]]; do

      if [[ "${disk[$disk_number]}" == "" ]]; then
        disk[$disk_number]=0
      fi

      if [[ $(( disk[disk_number] + file_size )) -lt ${bytelimit} ]]; then
        dir="${destdir_prefix}${disk_number}${destdir_suffix}"
        mkdir -p "${dir}"
        filedir="$(echo ${file} | sed 's|[^/]*$||g')"
        mkdir -p "${dir}/${filedir}"
        disk[$disk_number]=$(( disk[disk_number] + file_size ))
        echo "${disk[$disk_number]} ${dir}/${file}"
        cp "${file}" "${dir}/${file}"
        stored=true
      else
        disk_number=$(( disk_number + 1 ))
      fi
    done
  done

这将创建名为 disk_0、disk_1 等的文件夹。对于每个文件,它会尝试将文件放入 disk_0,如果不适合,则会尝试 disk_1 等。

于 2020-01-14T22:38:21.397 回答