Suppression de tous les fichiers d'un dossier à l'exception des fichiers X, Y et Z


17

J'ai beaucoup de fichiers et de dossiers dans un dossier spécifique et je veux les supprimer tous; cependant, je voulais conserver les fichiers X, Y et Z.

Existe-t-il un moyen de faire quelque chose comme: rm * | but NOT grep | X or Y or Z


Je suppose que je peux utiliser une expression régulière qui fera cela?
Amit

Réponses:


16

Au lieu d'utiliser rm, il peut être plus facile d'utiliser find . Une commande comme celle-ci supprimerait tout sauf un fichier nommé exactement «fichier»

find . \! -name 'file' -delete

De nombreuses versions de devraient pouvoir prendre en charge la globalisation et la correspondance d'expressions régulières.

Vous pouvez également diriger la sortie de find vers rm

find . \! -name '*pattern*' -print0 | xargs --null rm 

3
Et cela vous permet de voir exactement quels fichiers seront supprimés en supprimant le -deleteainsi que quels fichiers seront enregistrés en supprimant -deleteet le \!.
Shawn J. Goff

1
attention, findc'est récursif! de sorte que tous les sous-répertoires de fichiers ne correspondant pas au « modèle » seront également supprimés
Alexandre Holden Daly

Le chemin via xargs nécessite -depth, pour empêcher la tentative de suppression des répertoires avant les fichiers qui y sont inclus. Cependant, je pense que rm ne supprimera pas non plus les répertoires.
utilisateur inconnu

9

Utilisation de zsh, avec setopt EXTENDED_GLOB, à l'aide de l' ~opérateur ( sauf )

rm -- *~(x|y|z)

ou ^opérateur (négation):

rm -- ^(x|y|z)

Mais, vous devriez probablement déplacer les fichiers ailleurs, puis tout supprimer. C'est beaucoup plus sûr en termes de glissements de doigts, comme frapper trop tôt.


5

Les versions ultérieures de bash ont l' extgloboption shell qui vous donne une syntaxe pour faire ce que vous voulez (consultez votre page de manuel sous "Pathname Expansion" pour voir si votre version installée en dispose):

$ shopt -s extglob  # turn on extended globbing
$ rm !(X|Y|Z)

Pour tester, je vous suggère de remplacer d'abord rmpar echopour voir si la liste des fichiers à supprimer est celle que vous attendez.


5
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r

Attention: Exécutez la commande et si les fichiers à supprimer sont les bons, exécutez-la à nouveau et supprimez le caractère de hachage "#".

Si les noms de fichiers sont plus compliqués que cela, faites

ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r

Encore une fois, regardez d'abord les résultats, puis supprimez le signe de hachage.

Cette version - comme suggéré dans les commentaires - enregistre certains caractères et semble un peu plus claire.

ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r

Une modification suggérée par ddeimeke est de changer l' egrepargument en"^(file1|filename2|f1le)$"
Michael Mrozek

Si vous avez trois fichiers a, bet a ble premier programme supprimera - si vous mettez ab dans la partie grep: "^[ab]$" aet bnon a b, juste opposé à vos intentions. La deuxième commande fera de même. Et le troisième aussi. Vous ne devriez pas utiliser 'ls' dans les scripts, à de très, très rares exceptions près. Ne le fais pas.
utilisateur inconnu

3

Déplacez les fichiers que vous souhaitez conserver. Remontez d'un niveau, supprimez le dossier. Recréez le dossier et déplacez ces fichiers en arrière.


Je me demande pourquoi le moins? .. C'est en fait à la fois plus facile et plus sûr que tout ce que proposent les autres: vous ne pouvez tout simplement pas vous tirer une balle dans le pied en frappant un caractère spécial dans le nom du fichier.
alex

a) Vous déplacez votre fichier X d'un répertoire vers le haut, où un fichier X existe - supprimé silencieusement, disparu. b) Vous êtes dans le répertoire supérieur, où il n'y a pas de «haut» c) Vous êtes chez vous et n'avez pas la permission d'écrire à / home. Si vous mettez vos conseils dans un script, les testez sans problème et les utilisez dans une telle situation - peng!
utilisateur inconnu

2
a) Hé, ai-je dit «déplacer les fichiers d' un niveau»? J'ai dit de les éloigner. b) Donc, vous essayez de supprimer tous les fichiers /, hein? Pas très pratique. c) Essayer de supprimer tous les fichiers de votre $HOMEn'est pas vraiment pratique non plus.
alex

Tu as raison, je suis désolé.
utilisateur inconnu

0

C'est ce que j'ai configuré en tant que script .sh pour un hook de déconnexion OSX / MacOS, qui fonctionne assez bien.

#! /bin/bash
for dir in /PathToFolder/*
 do
    if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then 
      echo ${dir}
      sudo rm -R $dir user
      dscl . -delete $dir
    fi 
  done

exit 0

0

Avec GNU-find, vous pouvez utiliser le commutateur -delete, qui supprime également les répertoires, s'ils sont vides:

 find tmp -not -name X -not -name Y -not -name Z -delete 

Si X, Y ou Z est un répertoire, cela supprimera également les fichiers qu'ils contiennent. find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -deleteest une façon de contourner ce problème.
Gilles 'SO- arrête d'être méchant'

Étant donné que les dossiers sous Unix sont des fichiers (tout est un fichier), c'est peut-être ce qui est prévu. La question dit explicitement: "J'ai beaucoup de fichiers et de dossiers dans un dossier spécifique et je veux les supprimer tous;" - et si vous aimez exclure Y, vous savez peut-être si Y est un répertoire ou non.
utilisateur inconnu

Cela finira également par être supprimé tmps'il n'y avait pas de fichiers X/ Y/ Z. Remarque !comme l'équivalent standard de GNU -not( -deleteest également une extension GNU)
Stéphane Chazelas

@ StéphaneChazelas: De la question, la suppression des dossiers (tous) est ce qui était demandé. Puisque le coup a besoin de masquage, je préfère taper -not. Peut dépendre de la disposition du clavier allemand, où Backslash a besoin d'Alt-Gr.
utilisateur inconnu
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.