Question Comment supprimer tous les fichiers d'un répertoire, à l'exception de certains?


Je dois supprimer tous les fichiers d'un répertoire, mais en exclure certains. Par exemple, dans un répertoire avec les fichiers a b c ... z, Je dois tout supprimer sauf pour u et p. Y a-t-il un moyen facile de faire ceci?


119
2018-01-08 12:17


origine


Les réponses ci-dessous sont bien meilleures, mais vous pouvez simplement enregistrer les fichiers en lecture seule, tout supprimer, puis les restaurer à leurs autorisations d'origine (tant que vous n'utilisez pas rm -f). Vous devez savoir quelles autorisations restaurer et vous devez savoir que rien ne nécessite un accès en écriture pendant le processus. C'est pourquoi les autres réponses sont meilleures. - Joe
Si vous souhaitez également supprimer les fichiers cachés, exécutez shopt -s dotglob avant de courir rm (...).


Réponses:


Ce que je fais dans ces cas est de taper

rm *

Puis je presse Ctrl+X,* à développer  * dans tous les noms de fichiers visibles.

Ensuite, je peux simplement supprimer les deux fichiers que je souhaite conserver de la liste et enfin exécuter la ligne de commande.


108
2018-01-08 12:18



Je suppose que cela fonctionne seulement aussi longtemps que la liste des fichiers qui * se développe aussi ne devient pas trop long. : -} - Frerich Raabe
Esc suivi de * étendra également le "*". - slowpoison
@SantoshKumar: Cela n'a pas de sens pour moi. L'expansion fonctionnera toujours, cela ne dépend pas de la commande que vous souhaitez utiliser par la suite. - Der Hochstapler
@OliverSalzburg Désolé, la combinaison est un peu déroutante. Je pense que tu devrais écrire comme Ctrl + Shift + x + * - Santosh Kumar
@ SantoshKumar: Mais ce n'est pas la combinaison. - Der Hochstapler


À rm tout sauf u,p en bash, tapez simplement:

rm !(u|p)

Cela nécessite que l'option suivante soit définie:

shopt -s extglob

Voir plus: glob - Greg's Wiki


143
2018-01-08 12:34



vous devez avoir 'extglobbing' actif: shopt -s extglob - sparkie
Tu dois shopt -s extglob, @Un coup de feu. En outre, ce ne sont que des fichiers, pas des répertoires, ce qui explique pourquoi j'ai supprimé le -rf options dans votre commande. - slhck
Si vous devez exclure un fichier d'une sélection des fichiers, essayez ceci: rm !(index).html. Cela supprimera tous les fichiers se terminant par ".html" à l'exception de "index.html". - mzuther


Vous pouvez utiliser find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! annule l'expression suivante
  • -name spécifie un nom de fichier
  • -maxdepth 1 fera que find traite le répertoire spécifié uniquement (find par défaut traverse des répertoires)
  • -type f ne traitera que les fichiers (et pas par exemple les répertoires)
  • -delete va supprimer les fichiers

Vous pouvez ensuite régler les conditions en regardant le page de man de find

Mettre à jour

  • Gardez à l'esprit que l'ordre des éléments des expressions est significatif (voir la documentation)
  • Testez d'abord votre commande en utilisant -print au lieu de -delete

    find . ! -name u ! -name p -maxdepth 1 -type f -print
    

67
2018-01-08 12:35



@ Merci Dennis j'ai mis à jour la réponse - Matteo
l'ordre des prédicats est critique ici. Si on met -delete juste après . ce sera un désastre (supprimera tous les fichiers dans CWD) - Michał Šrajer
Cela pourrait être écrit de manière plus compacte que find . -maxdepth 1 -type f -name '[^up]' -delete - kojiro
@kojiro oui mais seulement pour les fichiers qui ne sont qu'une lettre. Avec des noms plus complexes, le regex pourrait être un gâchis. - Matteo
find est mon meilleur ami, surtout quand il y a trop de fichiers à globaliser - Terence Johnson


Simple:

mv les fichiers que vous voulez dans un répertoire supérieur, rm le répertoire puis mv leur retour.


42
2018-01-08 12:22



Offcourse, mv eux à un répertoire plus élevé. Essayez de ne pas les envoyer dans un sous-répertoire que vous supprimez ... - Konerak
@Konerak: rm sans pour autant -r ne supprimera pas les sous-répertoires. - reinierpost
Cela écrasera les fichiers avec le même nom dans le répertoire de destination - Matteo
Je vote ceci parce que, bien que cela puisse être utile, il est également non atomique et supprime efficacement tous les fichiers du répertoire pendant une courte période de temps; Cela ne serait pas acceptable si, par exemple, les fichiers étaient partagés sur le réseau. - sam hocevar


Quelque peu semblable à cette réponse mais aucune option spéciale n'est nécessaire, pour autant que je sache, la fonctionnalité suivante est "ancienne" supportée par n'importe quel shell (vaguement) / bin / sh (par exemple bash, zsh, ksh, etc.)

rm [^up]

15
2018-01-08 14:22



Cela fonctionne pour les noms de fichiers à 1 caractère. Pour les noms plus longs, la réponse de sparkie est meilleure. - glenn jackman
Quel serait le problème avec rm [^up]*? Je fais des choses similaires assez souvent. - Michael Kjörling
@ MichaelKjörling - Cela supprime tous les fichiers commençant par u ou p, pas seulement ceux portant les noms u et p. Je pense que l'OP (@Ashot) signifiait a-z et u, p, etc. symboliquement et non littéralement. - Sudipta Chatterjee
@HobbesofCalvin Cela supprime tous les fichiers ne pas en commençant par u ou p, pas ceux commençant par eux. - rjmunro
@rjmunro - merci, a manqué celui-là! :) - Sudipta Chatterjee


Le faire sans trouver:

ls | grep -v '(u|p)' | xargs rm

(Edit: "u" et "v", comme dans d’autres endroits, sont utilisés comme versions génériques de regexes entières. Évidemment, vous voudrez bien ancrer vos expressions rationnelles pour éviter de faire trop de choses.)

Vous allez certainement vouloir un script si vous en faites beaucoup, comme d'autres l'ont suggéré.


11
2018-01-09 03:54



grep ne gérera pas les regexpt étendus par défaut: -E ou egrep - Matteo
cela exclura tout fichier contenant un u ou un p - Matteo
@ Matteo Non ce ne sera pas. Le grep ne goute pas les fichiers, c’est la sortie de la commande ls. Vous pensez à quelque chose comme grep -L (u|p)' * | xargs rmoù -L signifie liste des noms de fichiers ne contenant pas de correspondance. - rjmunro
Oh, tu veux dire n'importe quel fichier qui contient le nom u ou p, pas un fichier contenant un u ou un p. C'est correct Vous pouvez corriger en utilisant egrep -v '^(u|p)$' - rjmunro
Ici on enlève tout sauf ces allumettes! ls | grep -v 'vuze\|progs' | xargs rm -rf - Nick


GLOBIGNORE prend une liste séparée par deux points

GLOBIGNORE=u:p
rm *

5
2018-01-08 16:32



Cela ne fonctionne pas sur mon shell (GNU bash 4.1.5 (1)). Assurez-vous de le tester d'abord avec quelque chose de moins nocif que rm ou dans un répertoire de test! - Michael Kjörling


Dans zsh:

setopt extended_glob  # probably in your .zshrc

puis

rm ^(u|p)

ou

rm *~(u|p)

La seconde fonctionnera même si vous avez ^ dans $histchars pour la substitution de l'histoire, et bien sûr vous pouvez mettre un glob arbitraire avant le ~.


5
2018-01-09 22:34





A l'époque des disquettes, j'avais un exécutable dosé appelé "Except" qui déplaçait temporairement les éléments du répertoire en cours et exécutait une commande, pour que vous puissiez dire:

sauf * .txt del *. *

supprimer tout sauf vos fichiers texte.

Ce serait une chose assez triviale à implémenter en tant que script shell et si c'est le genre de chose que vous êtes susceptible de faire plus de deux fois, il semble que ce serait une bonne idée.


3
2018-01-08 17:02



Cela m'a rappelé la même chose. Mais sortir temporairement d'un dossier n'est peut-être pas une bonne idée à l'ère du multitâche :) - Sedat Kapanoglu


 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Cela supprimera tous les fichiers sauf u et p dans unix


3
2018-01-08 17:58





Pour ceux qui préfèrent spécifier des patterns d'exclusion complexes arbitraires (couvrant tous les noms de fichiers affectés) dans un style d'expansion regexp complet emacs, posix-awk ou posix (voir la page de manuel de find), je recommanderais celui-ci. Il exclut u et p dans le répertoire courant dans cet exemple. Cela peut être pratique pour les scripts.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf

2
2018-01-08 18:16



Vous devez spécifier un répertoire avant l'expression (`find. -Regextype ...). - Matteo
-regextype ne fonctionnera que sur les versions GNU - Matteo
no - ma version find (debian squeeze) ne nécessite pas de répertoire explicite avant l'expression si le répertoire courant doit être utilisé - sparkie
@sparke: cela ne fonctionne que sur les implémentations GNU - Matteo
@sparkie: ne pas définir le répertoire (premier paramètre) pour find est une extension GNU de find commander. La même chose vaut pour -regextype option. De plus, votre commande supprime également les fichiers dans les sous-répertoires, alors que la question d'origine est clairement posée sur les fichiers d'un répertoire. - Mikko Rantalainen