52 votes

Comment "désextraire" un fichier zip ?

J'ai extrait un fichier zip dans un dossier non vide. Le fichier zip contient beaucoup de fichiers et une hiérarchie profonde, qui a fusionné avec l'arborescence existante du répertoire cible. Comment puis-je supprimer les fichiers et les répertoires créés par la décompression sans détruire les fichiers et les répertoires qui s'y trouvaient déjà ? Bien sûr, j'ai toujours le fichier zip que j'ai fusionné, donc l'information est là.

28voto

jjlin Points 14572

Vous pouvez utiliser unzip -lqq <filename.zip> pour lister le contenu du fichier zip ; il contiendra des informations parasites que vous devrez filtrer. Voici une commande qui fonctionne pour moi :

unzip -lqq file.zip | awk '{print $4;}' | xargs rm -rf

En awk extrait uniquement les noms des fichiers et des répertoires. Le résultat est ensuite transmis à xargs pour tout effacer. Je suggère de faire un essai à blanc de la commande (c'est-à-dire en omettant l'élément xargs rm -rf ) pour s'assurer que les résultats sont corrects.

La commande ci-dessus aura des difficultés à traiter les chemins d'accès contenant des espaces. Cette version (plus compliquée) devrait résoudre ce problème :

unzip -lqq file.zip | awk '{$1=$2=$3=""; sub(/ */, "", $0); printf "%s%s", $0, "\0"}' | xargs -0 rm -rf

28voto

Mohsin Points 11

jjlin est la meilleure solution. Je voudrais juste ajouter quelques choix d'annuaires :

  • Supprimer tous les extraits fichiers, pas de répertoires :

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm "$n"; done
  • Supprimer les fichiers extraits et vide répertoires uniquement

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm "$n"; done; rmdir *

    Sans aucune option, rmdir ne supprime que les répertoires vides, il laisse les fichiers et les dossiers non vides tranquilles. * .

  • Supprimer tout extraites, mais demandent une confirmation avant chaque suppression :

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm -ri "$n"; done; rmdir *

    En -i entraînera l'utilisation de l'indicateur rm pour vous inviter à le faire avant chaque suppression, vous pouvez choisir Oui ou Non.

  • Supprimer tout extraites, répertoires inclus :

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm -rf "$n"; done

11voto

Dennis Points 46916

Avec l'interrupteur -Z1 unzip listera exactement un fichier par ligne (et rien d'autre).

De cette façon, vous pouvez utiliser

unzip -Z1 | xargs -I {} rm '{}'

pour supprimer tous les fichiers extraits du fichier zip.

La commande

unzip -Z1 | xargs -I {} rm -rf '{}'

supprime également les répertoires, mais il faut être prudent. Si les répertoires existaient déjà avant l'extraction du fichier zip, tous les fichiers préexistants dans ces répertoires seront également supprimés.


Si vous avez l'intention de réextraire le fichier zip de toute façon, il existe une autre approche qui garantit la prise en charge des noms de fichiers étranges.

Commencez par extraire le fichier zip à l'endroit où vous deviez l'extraire à l'origine :

unzip file.zip -d elsewhere

Maintenant, allez dans le répertoire où vous avez extrait les fichiers par erreur et exécutez la commande suivante :

find elsewhere -type f -printf "%P\0" | xargs -0 -I {} rm '{}'
  • -type f ne trouve que des fichiers (pas de répertoires).

  • %P\0 est le chemin relatif (sans elsewhere/ ), suivi d'un caractère nul.

  • -0 permet à xargs de séparer les lignes par des caractères nuls. Cette méthode est plus fiable, puisque - en théorie - les noms de fichiers peuvent contenir des caractères de retour à la ligne.


Pour traiter les répertoires restants, vous pouvez exécuter la commande :

find -type d -exec rmdir -p {} \; 2> /dev/null
  • -type d ne trouve que des répertoires.

  • -exec rmdir -p {} \; exécute rmdir -p {} pour chaque répertoire trouvé.

    {} est le répertoire qui a été trouvé, et l'élément -p fait en sorte que rmdir supprime également ses répertoires parents vides.

  • 2> /dev/null supprime les messages d'erreur qui surviennent lorsque l'on tente de supprimer des répertoires non vides ou précédemment supprimés.


Pages de manuel connexes :

2voto

David E. Points 51

Voici une solution encore plus simple et plus sûre (je pense)

zip -m getmeoutofhere.zip `unzip -lqq myoriginalzipfile.zip`
rm getmeoutofhere.zip

Ce qu'il fait : La commande Unzip citée à l'envers produit une liste de ce qui se trouve dans le fichier original.

zip -m utilisera alors cette liste pour ajouter chacun d'entre eux à getmeoutofhere.zip et le retirer du répertoire d'origine (donc théoriquement, il devrait être indépendant de myoriginalfile.zip).

L'inconvénient est que unzip -lqq produira du texte supplémentaire, des dates, des heures, la taille des fichiers, etc. Ces éléments feront que zip -m produira des messages d'erreur, mais cela ne devrait pas avoir d'incidence (à moins que vous n'ayez le cas improbable d'un fichier portant le même nom).

Veuillez noter que cette opération ne supprimera pas les répertoires créés lors de la décompression initiale.

1voto

Kaz Points 2554

Si vous avez extrait les fichiers de telle sorte que l'heure de modification de l'archive n'est pas conservée dans les copies extraites (mais que les fichiers extraits ont leur heure de modification habituelle), la bonne façon d'attaquer ce problème est d'utiliser l'heure de modification. Tous les fichiers extraits ont une date de modification plus récente que le fichier existant le plus récemment modifié dans ce répertoire.

Voici une situation simple.

Supposons qu'aucun des fichiers existants dans le répertoire actuel n'ait été touché pendant au moins 24 heures. Tout ce qui a été modifié au cours des dernières 24 heures est donc supprimé du fichier zip.

$ find . -mtime -1 -print0 | xargs -0 rm

Cela permettra de trouver certains répertoires, mais rm les laisseront tranquilles. Ils peuvent être traités lors d'un deuxième passage :

$ find . -mtime 1 -type d -print 0 | xargs -0 rmdir

Tous les répertoires récemment modifiés ont été modifiés par le zip. Si le rmdir les supprime avec succès, ce qui signifie qu'ils sont vides. Les répertoires vides qui ont été touchés par zip ont probablement été créés par lui : c'est-à-dire qu'ils proviennent de l'archive. Nous ne pouvons pas en être sûrs à 100 %. Il est possible que le travail de décompression ait placé des fichiers dans un répertoire existant qui était vide.

Si find n'est pas suffisante pour le travail, parce que les fichiers de l'arbre ont été modifiés trop récemment, alors j'envisagerais quelque chose de simple : supposons que le travail de décompression n'ait rien mis dans les sous-répertoires existants. En d'autres termes, tout ce qui a été décompressé est soit un fichier au niveau supérieur, soit un nouveau sous-répertoire qui n'existait pas auparavant et qui ne contient donc rien d'autre que du matériel provenant de la décompression. Dans ce cas, il s'agit d'un fichier au niveau supérieur :

# list directory in descending order of modification time
$ ls -1t > filelist  # descending order of modification time

Nous ouvrons maintenant filelist dans un éditeur de texte, et déterminez la première entrée de la liste qui ne provient pas du zip. Nous supprimons cette entrée et toutes celles qui la suivent. Il ne reste plus que les fichiers et les répertoires qui proviennent du zip. Tout d'abord, nous procédons à une inspection visuelle pour détecter les espaces dans les noms et les guillemets qui doivent être échappés. Nous pouvons alors ajouter des guillemets autour de tout, si nécessaire : Ce qui suit suppose que vous utilisez Vim :

:%s/.*/"&"/

Ensuite, le tout est regroupé en une grande ligne :

:%j

Insérer maintenant rm -rf devant elle :

Irm - rf<ESC>

Exécutez la ligne sous le curseur comme une commande Shell :

!!sh<Enter>

Je n'automatiserais certainement pas les étapes de cette tâche, en raison du risque d'effacer des fichiers déjà présents, ou de se tromper en raison de problèmes de noms de fichiers.

Si vous optez pour la solution évidente qui consiste à obtenir une liste des chemins d'accès dans le fichier zip, capturez-la dans un fichier, examinez-la très attentivement et transformez-la en suppression après avoir effectué toutes les modifications nécessaires.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X