Comment recompresser 2 millions de files gzip sans les stocker deux fois?

J'ai environ 2 millions (60GiB) de petits files gzipped et je voudrais créer une archive compressée contenant tous dans une version non compressée. Malheureusement, je ne peux pas simplement les décompresser tous, puis créer l'archive compressée car j'ai seulement environ 70 Go d'espace disque disponible. En d'autres termes, comment puis-je faire un équivalent du tar --file-filter="zcat" zcf file.tar.gz directory si le commutateur de command line comme --file-filter n'existe pas dans GNU tar?

Une option pourrait être d'utiliser avfs (ici en supposant un système 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 

Prenez note, que c'est fragile quand il s'agit de noms de files méchants.

 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" 

Les files sont décompressés temporairement sous $tmpdir , transmis à cpio dès qu'ils sont ajoutés à l'archive, supprimés.

Voici ce que j'ai essayé jusqu'à présent – il semble fonctionner, mais est terriblement lent, même avec PyPy:

 #!/usr/bin/python import tarfile import os import gzip import sys import cSsortingngIO 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 = cSsortingngIO.SsortingngIO(b) tar.addfile(ti, io) tar.close() 

Utilisation: find . | script.py | gzip > file.tar.gz find . | script.py | gzip > file.tar.gz