サイズに応じて、ディレクトリ内のm個のファイルをn個のtarファイルに入れますか?

サイズに応じて、ディレクトリ内のm個のファイルをn個のtarファイルに入れますか?

tarディレクトリ内の大きなファイルのコレクションからn個のファイル(ほぼ同じサイズ)を作成して個別に抽出できるかどうかを知っていますか?

オプションを探していますが、残念ながら元のファイルを抽出するには生成されたtar --multi-lineすべてのファイルが必要です。 -ingをtar使用してtarからsplit-ingファイルを使用すると、さらにそうです。

ほぼ同じサイズである必要がない場合は、ls | wcディレクトリ内のファイル数を取得し、ファイル名を同じサイズのセット(たとえばls | tail -n900| head -n100)に分割してに渡すと言いたいと思いますtar。おそらくかなりの大きさの変化で終わるでしょう。

どんなアイデアがありますか?

答え1

ファイルサイズを確認するスクリプトを作成できます。ごみ箱に配分してください。、最大サイズを超えないように注意してください。最適な解決策は単純ではないかもしれませんが、グリディアルゴリズムは単純でなければなりません。

tar1つのマイナーな問題は、ファイルの内容に加えて占める帳簿スペースを考慮することです。 (また、ディレクトリと特殊ファイルを処理する方法は何ですか?)

アーカイブを圧縮しようとすると、より大きな問題が発生します。一般的なイディオムはファイルを一緒に保持し、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
    }
}

関連情報