Supposons que j'ai un gzip compressé tar-ball compressedArchive.tgz (+100 fichiers, totalisant + 5 Go).
Quel serait le moyen le plus rapide de supprimer toutes les entrées correspondant à un modèle de nom de fichier donné par exemple préfixe * .jpg, puis stockez les restes dans une gzip: éd tag-ballon à nouveau?
Remplacer l'ancienne archive ou la création d'un nouveau n'est pas important, selon la première éventualité la plus rapide.
Avec GNU tar
, vous pouvez faire:
pigz -d < file.tgz |
tar --delete --wildcards -f - '*/prefix*.jpg' |
pigz > newfile.tgz
Avec bsdtar
:
pigz -d < file.tgz |
bsdtar -cf - --exclude='*/prefix*.jpg' @- |
pigz > newfile.tgz
(pigz
étant la version multi-threadée de gzip
).
Vous pouvez écraser le fichier sur lui-même comme:
{ pigz -d < file.tgz |
tar --delete --wildcards -f - '*/prefix*.jpg' |
pigz &&
Perl -e 'truncate STDOUT, tell STDOUT'
} 1<> file.tgz
Mais c'est assez risqué, surtout si le résultat finit par être moins compressé que le fichier d'origine (auquel cas, le deuxième pigz
peut finir par écraser les zones d'écrasement du fichier que le premier n'a pas encore lu).
Ne négligez pas le moyen facile: il peut être assez rapide pour votre but. Avec AVFS Pour accéder à l'archive en tant que répertoire:
cd ~/.avfs/path/to/original.tar.gz\#
pax -w -s '/^.*\.jpg$//' | gzip >/path/to/filtered.tar.gz # POSIX
tar -czf /path/to/filtered.tar.gz -s '/^.*\.jpg$//' . # BSD
tar -czf /path/to/filtered.tar.gz --transform '/^.*\.jpg$//' . # GNU
Avec des outils plus primitifs, extrait d'abord les fichiers à l'exclusion de l'.jpg
Fichiers, puis créez une nouvelle archive.
mkdir tmpdir && cd tmpdir
<original.tar.gz gzip -d | pax -r -pe -s '/^.*\.jpg$//'
pax -w . | gzip >filtered.tar.gz
cd .. && rm -rf tmpdir
Si votre goudron a --exclude
:
mkdir tmpdir && cd tmpdir
tar -xzf original.tar.gz --exclude='*.jpg'
tar -czf filtered.tar.gz .
cd .. && rm -rf tmpdir
Cela peut toutefois mangler la propriété et les modes de fichiers si vous ne l'exécutez pas en tant que root. Pour de meilleurs résultats, utilisez un répertoire temporaire sur un système de fichiers rapide - TMPFS si vous en avez une assez grande.
Soutien aux archiveurs d'agir comme une passage (c'est-à-dire une archive et écrire une archive) a tendance à être limitée. GNU TAR peut supprimer des membres d'une archive avec le --delete
option de fonctionnement ("The --delete
L'option a été signalée correctement lorsque tar
agit en tant que filtre de stdin
à stdout
. "), et c'est probablement votre meilleure option.
Vous pouvez faire de puissants filtres d'archives dans quelques lignes de python. Son tarfile
Bibliothèque peut lire et écrire à partir de flux non recherchables, et vous pouvez utiliser le code arbitraire dans Python pour filtrer, renommer, modifier, modifier ...
#!/usr/bin/python
import re, sys, tarfile
source = tarfile.open(fileobj=sys.stdin, mode='r|*')
dest = tarfile.open(fileobj=sys.stdout, mode='w|gz')
for member in source:
if not (member.isreg() and re.match(r'.*\.jpg\Z', member.name)):
sys.stderr.write(member.name + '\n')
dest.addfile(member, source.extractfile(member))
dest.close()
Pour ce faire, vous devez probablement extraire tout la contenante du fichier .tgz dans un dir local puis effacez les fichiers que vous ne souhaitez pas, puis recompretez le .tgz.
C'est long et vous avez besoin de suffisamment d'espace disque gratuit, mais au meilleur de ma connaissance, il n'y a pas d'autre moyen de le faire.
Étant donné que vous avez déjà un chemin comme /tmpdir/withalotofspace
qui ont un espace libre suffisant (vérifiez-le en utilisant df -h /tmpdir/withalotofspace
), tu peux faire quelque chose comme ça:
$ cd /tmpdir/withalotofspace
$ tar -xvfz /path/to/compressedArchive.tgz
$ find /tmpdir/withalotofspace/ -type f -iname '*.jpg' -delete
$ tar -cvzf /path/to/purgedcompressedArchive.tgz .
J'aime la réponse de @gilles, sauf que cela peut être encore simplifié. Après avoir décompressé, par exemple gunzip foo.tgz
le fichier sera foo.tar
et les fichiers peuvent être supprimés avec tar -f foo.tar --delete file|directory
. Vous trouverez ci-dessous un exemple d'élimination d'un répertoire à partir d'un fichier de goudron.
phablet@ubuntu-phablet:~/Downloads$ tar -cvf moo.tar moo1/
moo1/
moo1/moo2/
moo1/moo2/moo3/
moo1/moo2/moo3/moo4/
moo1/moo2/moo3/moo4/moo5/
phablet@ubuntu-phablet:~/Downloads$ tar -tf moo.tar
moo1/
moo1/moo2/
moo1/moo2/moo3/
moo1/moo2/moo3/moo4/
moo1/moo2/moo3/moo4/moo5/
phablet@ubuntu-phablet:~/Downloads$ tar -f moo.tar --delete "moo1/moo2/moo3"
phablet@ubuntu-phablet:~/Downloads$ tar -tf moo.tar
moo1/
moo1/moo2/
Les types de fichiers spécifiques peuvent être trouvés avec tar -tf foo.tar|egrep -i '.jpg$'
.
J'utilise:
tar -xvf myLarge.gz --exclude "prefix" | tar -czvf myLarge.gz -T -
Cette volonté:
-T -
) Tuyau repose au goudron et re-compresse mylarge.gz