それぞれのサイズが約3〜10 GBの数千のファイルを含む複数のフォルダがあります。今、これらのファイルをフォルダにパッケージ化したいと思います。各tarファイルのサイズは約1 GBでなければなりません。後でPythonを使用してこれらのtarファイルを処理したいと思います。
#!/bin/bash
dirlist=$(find $1 -mindepth 1 -maxdepth 1 -type d)
stored_date=$(date +%Y-%m-%d --date="-1 day")
#stored_date='2019-10-23'
for dir in $dirlist
do
(
cd $dir
tar_file=${PWD##*/}
tar_file="${tar_file}_${stored_date}.tar"
echo "${tar_file}"
tar -c $stored_date*.html --tape-length=1000M -f ${tar_file} --remove-files
)
done
1GBのチャンクを生成するのはうまくいきますが、Pythonには "--tape-length"オプションを使用するときにあらゆる種類の問題があります。
tarfile.ReadError: 予期しないデータの終わり
(また、Pythonを使用してtarアーカイブの端から分割されたファイルを処理したい)
Linuxにこの問題に対する解決策はありますか? tarの代わりにstarを見つけましたが、まだ試していません。可能であれば、標準のtarを使用することをお勧めします。
答え1
tarファイルに追加する前に、各ファイルのサイズを追跡するために各ディレクトリループ内に2番目のループを入れ子にするのはどうですか?私が意味するものの概略的な擬似コードは次のとおりです。
max_size=$((1024*1024*1024))
total_size=0
for dir in $dirlist ; do
for foo in $dir/*; do
this_size="$(stat -c"%s" $foo)"
if [ $(($total_size + $this_size)) -le $max_size ] ; then
tar --append ... $foo
total_size="$(($total_size + $this_size))"
else
# start new tar file here
tar -c ... $foo
total_size="$this_size"
fi
done
done
答え2
私が知っている限り、Pythonはtar形式を理解していないので、tarアーカイブ標準と100%互換性のないtarアーカイブモジュールを使用する方が良いかもしれません。これは考慮すべき重要な事項です。公式の機能セットのサブセットのみをサポートする未完成のtar実装がたくさんあります。
モードに入らずにこのオプションを使用することをお勧めしますstar
。これにより、ファイルが途中で分割されるのを防ぎますが、指定されたテープサイズより大きいファイルは保持できません。-tsize
star
multi volume
star
デフォルトのシェル "sh" が "$((expr))" サポートで POSIX 仕様である場合、そうでない場合は、 "sh -c" を "ksh -c" またはそれと同じものに置き換えます。
...どうですか?
cd /tmp
star -C path/to/archivedir -c tsize=1G \
new-volume-script='cd /tmp;sh -c "mv vol-last.tar vol\$((\$1-1)).tar" script' \
f=vol-last.tar .
これにより、生成されたTARアーカイブが/ tmpに残ります。 vol-last.tarの名前を最終予想ボリューム番号に手動で変更する必要があります。最後のアーカイブを含め、すべてのアーカイブの最後まで新しいボリュームスクリプトを実行するようにスターを拡張することを検討できます。