Directory 自动复制文件夹,直到达到某个限制
你好 1-假设我有大约500个大小可变的文件夹,总大小为100GB 2-我想在其他文件夹中自动分发这些文件夹,直到达到700 MB的大小,并对空间进行最佳优化 示例:在文件夹“CD--01”中,我希望在不超过700MB限制的情况下,拥有尽可能多的文件夹,以此类推,在“CD--02”、“CD--03”中 有没有一个工具可以让我“即时”完成这项工作,或者我必须自己编写一个 谢谢如果您使用的是UNIX(包括Mac OSX),您可以编写如下脚本Directory 自动复制文件夹,直到达到某个限制,directory,copying,Directory,Copying,你好 1-假设我有大约500个大小可变的文件夹,总大小为100GB 2-我想在其他文件夹中自动分发这些文件夹,直到达到700 MB的大小,并对空间进行最佳优化 示例:在文件夹“CD--01”中,我希望在不超过700MB限制的情况下,拥有尽可能多的文件夹,以此类推,在“CD--02”、“CD--03”中 有没有一个工具可以让我“即时”完成这项工作,或者我必须自己编写一个 谢谢如果您使用的是UNIX(包括Mac OSX),您可以编写如下脚本 tar cvzf allfolders.tgz ./all
tar cvzf allfolders.tgz ./allfolders
split allfolders.tgz -b 700m
这将创建所有文件夹的(压缩)存档,然后将其拆分为700M大小的块。但是,当您想要重建原始文件夹集时,需要重新组合所有片段,然后使用tar再次提取
如果你想将它们作为单独的操作系统文件夹保存在CD上,那是相当困难的(事实上,我认为这是一种背包问题,这是NP难的)。有一些工具可以做到这一点-类似于frankodwyer的答案,将把你的100GB压缩,并将其分成你想要的任何大小的“块”——即约700MB
这是一个非常幼稚且编码不好的解决方案,但它确实有效。我的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
最终,你是在寻求解决问题的办法,而这一办法即将到来 一种简单的方法是根据以下伪代码,但这将而不是为所有输入生成最佳解决方案(请参阅上面的文章)
while(存在未分配的文件){
创建一个新的空目录
将剩余空间设置为70000000
虽然(最小的未分配的大小最多(我参加聚会有点晚,但我是如何解决问题的:
#!/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等。以最佳方式执行此操作是背包问题。对于任何非平凡的数据集,都无法在合理的时间内解决。非最佳方式是可行的。不,不是,文件没有价值。that起到了很大的作用。感谢Sparr…我不在UNIX下…但我可以在Win和UNIX虚拟机之间共享一个文件夹并运行该脚本。我会尝试一下。bash可通过cygwin在windows上使用,不过必须考虑一些问题,如驱动器号和\vs/等,正如joel.neely的回答所指出的,one ob最明显的改进是寻找更小的东西移动到一个几乎完整的目录中,而不是在下一个项目不适合当前ont时立即创建一个新的目录。
#!/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