Directory 自动复制文件夹,直到达到某个限制

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

你好

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

2-我想在其他文件夹中自动分发这些文件夹,直到达到700 MB的大小,并对空间进行最佳优化

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

有没有一个工具可以让我“即时”完成这项工作,或者我必须自己编写一个

谢谢

如果您使用的是UNIX(包括Mac OSX),您可以编写如下脚本

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