将一个目录下的m个文件按大小放入n个tar文件中?

将一个目录下的m个文件按大小放入n个tar文件中?

有谁知道是否可以tar从一个目录中的较大文件集合中创建 n 个文件(大小大致相等),以便可以单独提取它们?

我正在寻找tar --multi-line选项,但不幸的是,看起来所有生成的tar文件都是提取原始文件所必需的。使用tar-ing 然后split-ing 文件更是如此。

如果它们不必具有大致相同的大小,我会说 dols | wc来获取目录中的文件数量,然后将文件名拆分为大小相等的集合(类似于:ls | tail -n900| head -n100),并将它们传递给tar.但最终您可能会得到相当大的尺寸变化。

有任何想法吗?

答案1

您可以编写一个脚本来查看文件的大小并将它们分发到垃圾箱中,注意不要超过最大尺寸。最优解可能并不简单,但贪心算法应该可以。

tar一个小问题是除了文件内容之外还要考虑所占用的簿记空间。 (还有,如何处理目录和特殊文件?)

如果你想压缩档案,就会出现更大的问题。由于通常的习惯用法是将文件放在一起tar并使用单独的实用程序压缩 tar 文件,因此沿文件边界分割生成的存档并不那么简单。您非常需要提前知道文件的压缩大小。如果您在将文件tar组合在一起之前对其进行压缩,则可以知道其大小,但会失去一次性压缩所有文件的空间优势。


事实上,我制作了一个简单的awk脚本来在某个时候做到这一点。下面的代码,与使用

find dir/ -printf "%s\t%p\n" | sort -n | awk -vmax=$maxsizeinbytes -f pack.awk

(输出到bins.list.NNN。没有保证,不适用于包含空格的文件名,可能还有其他错误等。)

#!/usr/bin/awk
# pack.awk
{ 
    if ($1 > max) {
        printf "too big (%d, max %d): ", $1, max, $2 > "/dev/stderr";
        exit 1;
    }
    for (x in bins) {
        if (free[x] >= $1) { 
            bins[x] = bins[x] "\n" $2; 
            count[x]++; free[x] -= $1; 
            next 
        }
    }; 
    bins[++i] = $2; free[i] = max - $1; count[i] = 1;
} 
END {
    for (i in bins) {
        printf "bin %d: entries: %d size: %d \n", i, count[i], max - free[i]; 
        print bins[i] > "bins.list." i
    }
}

相关内容