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

时间:2022-01-06 21:26:19

Greetings.

1 - Let's say I have about 500 folders of variable size with a total size of 100 GB.

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

2 - I want to distribute these folders automatically in other folders until the size of 700 MB is reached with the best optimization of space.

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

Example: In folder "CD--01" I want to have the maximum number of folders possible without passing the limit of 700 MB, and so on in "CD--02", "CD--03"...

示例:在“CD-01”文件夹中,我希望在不通过700 MB限制的情况下获得最大文件夹数,依此类推“CD-02”,“CD-03”......

Is there a tool that allows me to do this "on the fly" or will I have to code one myself?

有没有一个工具允许我“动态”执行此操作,还是我必须自己编写代码?

Thanks

4 个解决方案

#1


This is a very naive and poorly coded solution, but it works. My bash-fu is not strong, but a shell script seems like the best way to approach this problem.

这是一个非常天真和编码不佳的解决方案,但它的工作原理。我的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

#2


Ultimately you're asking for a solution to the Knapsack Problem, which comes in many forms.

最终你要求解决背包问题,它有多种形式。

A simple approach would be per the following pseudocode, but this will not produce optimal solutions for all inputs (see the articles above).

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

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
}

(Of course, this assumes that no single file will be greater than 700MB in size. If that's possible, be sure to remove any such files from the unallocated list, else the above will produce infinitely many empty directories! ;-)

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

#3


If you're on UNIX (inc Mac OSX) you can script something like

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

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

This will create a (compressed) archive of all the folders and then split it into 700M sized chunks. However you'll need to recombine all the pieces then extract again using tar, when you want to reconstitute the original folder set.

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

If you want to keep them as individual OS folders on the CD, that's fairly difficult (in fact I think it's a kind of knapsack problem, which is NP-hard).

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

#4


There are tools that will do this - similar to frankodwyer's answer, WinZip will take your 100GB, zip it up and split it into any size 'chunks' you'd like - i.e. ~700MB

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

Here's the page the WinZip split feature

这是WinZip拆分功能的页面

#1


This is a very naive and poorly coded solution, but it works. My bash-fu is not strong, but a shell script seems like the best way to approach this problem.

这是一个非常天真和编码不佳的解决方案,但它的工作原理。我的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

#2


Ultimately you're asking for a solution to the Knapsack Problem, which comes in many forms.

最终你要求解决背包问题,它有多种形式。

A simple approach would be per the following pseudocode, but this will not produce optimal solutions for all inputs (see the articles above).

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

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
}

(Of course, this assumes that no single file will be greater than 700MB in size. If that's possible, be sure to remove any such files from the unallocated list, else the above will produce infinitely many empty directories! ;-)

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

#3


If you're on UNIX (inc Mac OSX) you can script something like

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

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

This will create a (compressed) archive of all the folders and then split it into 700M sized chunks. However you'll need to recombine all the pieces then extract again using tar, when you want to reconstitute the original folder set.

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

If you want to keep them as individual OS folders on the CD, that's fairly difficult (in fact I think it's a kind of knapsack problem, which is NP-hard).

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

#4


There are tools that will do this - similar to frankodwyer's answer, WinZip will take your 100GB, zip it up and split it into any size 'chunks' you'd like - i.e. ~700MB

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

Here's the page the WinZip split feature

这是WinZip拆分功能的页面