问候。
1 - 假设我有大约500个可变大小的文件夹,总大小为100 GB。
2 - 我希望在其他文件夹中自动分发这些文件夹,直到达到700 MB的大小并获得最佳的空间优化。
示例:在“CD-01”文件夹中,我想在不通过700 MB限制的情况下获得最大文件夹数,依此类推“CD-02”,“CD-03”..
是否有工具允许我“动态”执行此操作,还是我必须自己编写代码?
由于
答案 0 :(得分:2)
最终,您要求找到Knapsack Problem in many forms的解决方案。
一种简单的方法是按照以下伪代码,但这将不为所有输入生成最佳解决方案(参见上面的文章)。
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。如果可能,请务必从未分配的列表中删除任何此类文件,否则上面会生成无限多个空目录!;-)
答案 1 :(得分:0)
如果您使用的是UNIX(包括Mac OSX),则可以编写类似
的脚本tar cvzf allfolders.tgz ./allfolders
split allfolders.tgz -b 700m
这将创建所有文件夹的(压缩)存档,然后将其拆分为700M大小的块。但是,当您想重新构建原始文件夹集时,您需要重新组合所有碎片然后再使用tar提取。
如果你想将它们作为单独的OS文件夹保存在CD上,那就相当困难了(事实上我认为这是一种背包问题,这是NP难的)。
答案 2 :(得分:0)
有一些工具可以做到这一点 - 类似于frankodwyer的回答,WinZip将你的100GB,拉链并将其拆分成你想要的任何大小的“块” - 即〜700MB
答案 3 :(得分:0)
这是一个非常天真且编码不佳的解决方案,但它确实有效。我的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
答案 4 :(得分: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,等等。