3000万の小さなファイルを含む大きなフォルダがあります。フォルダを30個のアーカイブにバックアップしたいです。各 tar.gz ファイルには 1M ファイルがあります。複数のアーカイブに分割する理由は、大容量アーカイブを解凍するのに1ヶ月かかるからです。ファイルを解凍するときにすべてのアーカイブをまとめる必要があるため、分割するパイピングtarも機能しません。
また、各ファイルを新しいディレクトリに移動しないことを好みます。なぜなら、この巨大なフォルダにはlsも非常に痛みを伴うでしょう。
ベストアンサー1
これを行うには、このbashスクリプトを作成しました。デフォルトでは、各tarに入るファイル名で配列を形成しtar
、これらはすべて平行です。。これは最も効率的な方法ではないかもしれませんが、必要な方法で作業を完了できます。しかし、メモリ消費が多いと予想されます。
スクリプトの先頭でオプションを調整する必要があります。cvjf
最後の行のtarオプションを変更することもできます(たとえば、v
パフォーマンスを向上させるために詳細な出力を削除したり、圧縮を次にj
変更するz
など)。
スクリプト
#!/bin/bash
# User configuratoin
#===================
files=(*.log) # Set the file pattern to be used, e.g. (*.txt) or (*)
num_files_per_tar=5 # Number of files per tar
num_procs=4 # Number of tar processes to start
tar_file_dir='/tmp' # Tar files dir
tar_file_name_prefix='tar' # prefix for tar file names
tar_file_name="$tar_file_dir/$tar_file_name_prefix"
# Main algorithm
#===============
num_tars=$((${#files[@]}/num_files_per_tar)) # the number of tar files to create
tar_files=() # will hold the names of files for each tar
tar_start=0 # gets update where each tar starts
# Loop over the files adding their names to be tared
for i in `seq 0 $((num_tars-1))`
do
tar_files[$i]="$tar_file_name$i.tar.bz2 ${files[@]:tar_start:num_files_per_tar}"
tar_start=$((tar_start+num_files_per_tar))
done
# Start tar in parallel for each of the strings we just constructed
printf '%s\n' "${tar_files[@]}" | xargs -n$((num_files_per_tar+1)) -P$num_procs tar cjvf
説明する
まず、選択したパターンに一致するすべてのファイル名が配列に保存されますfiles
。次に、forループは配列を分割し、その分割で文字列を形成します。スライス数は必要なタールボール数と同じです。結果の文字列は配列に保存されますtar_files
。 forループはまた、生成されたtarballの名前を各文字列の先頭に追加します。の要素はtar_files
次の形式をとります(5つのファイル/タールボールと仮定):
tar_files[0]="tar0.tar.bz2 file1 file2 file3 file4 file5"
tar_files[1]="tar1.tar.bz2 file6 file7 file8 file9 file10"
...
スクリプトの最後の行は、複数のプロセス(指定された最大数まで)を開始xargs
するために使用され、各プロセスは配列の1つの要素を並列に処理します。tar
tar_files
テスト
ファイルリスト:
$ls
a c e g i k m n p r t
b d f h j l o q s
生成された圧縮パッケージ: $ls /tmp/tar* tar0.tar.bz2 tar1.tar.bz2 tar2.tar.bz2 tar3.tar.bz2