約200万個(60GiB)の小さなgzipファイルがあり、すべてのファイルの非圧縮バージョンを含む圧縮アーカイブを作成したいと思います。残念ながら、空きディスク容量は約70GiBしかないため、すべての圧縮を解放して圧縮アーカイブを作成することはできません。つまり、GNU tarにtar --file-filter="zcat" zcf file.tar.gz directory
そのようなコマンドラインスイッチがない場合、どのように同等の操作を実行できますか?--file-filter
答え1
1つのオプションは次のとおりです。avfs
(これはGNUシステムを想定しています):
mkdir ~/AVFS &&
avfsd ~/AVFS &&
cd ~/AVFS/where/your/gz/files/are/ &&
find . -name '*.gz' -type f -printf '%p#\0' |
tar --null -T - --transform='s/.gz#$//' -cf - | pigz > /dest/file.tar.gz
答え2
不快なファイル名の場合、これは脆弱であることに注意してください。
dir_with_small_files=/home/john/files
tmpdir=/tmp/ul/dst
tarfile=/tmp/ul.tar
mkfifo "${tarfile}"
gzip <"${tarfile}" >"${tarfile}.gz" &
find "$dir_with_small_files" -type f | \
while read src; do
dstdir="${tmpdir}/$(dirname $src)"
dst="$(basename $src .gz)"
mkdir -p "$dstdir"
gunzip <"$src" >"${dstdir}/${dst}"
# rm "$src" # uncomment to remove the original files
echo "${dstdir}/${dst}"
done | \
cpio --create --format=ustar -v --quiet 2>&1 >"${tarfile}" | \
while read x; do
rm "$x"
done
# clean-up
rm "$tarfile"
rm -r "$tmpdir"
以下のファイルは一時的に解凍され、すぐに渡され、$tmpdir
アーカイブに追加されるとすぐに削除されます。cpio
答え3
これまでに試したことは次のとおりです。動作しているように見えますが、PyPyを使用しても非常に遅いです。
#!/usr/bin/python
import tarfile
import os
import gzip
import sys
import cStringIO
tar = tarfile.open("/dev/stdout", "w|")
for name in sys.stdin:
name = name[:-1] # remove the trailing newline
try:
f = gzip.open(name)
b = f.read()
f.close()
except IOError:
f = open(name)
b = f.read()
f.close()
# the [2:] there is to remove ./ from "find" output
ti = tarfile.TarInfo(name[2:])
ti.size = len(b)
io = cStringIO.StringIO(b)
tar.addfile(ti, io)
tar.close()
使用法:find . | script.py | gzip > file.tar.gz