web-dev-qa-db-fra.com

Supprimer tous les fichiers sauf certains d'un répertoire

Lorsque vous utilisez Sudo rm -r, comment puis-je supprimer tous les fichiers, à l'exception des éléments suivants:

textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
203
masjoko
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete

Si vous ne spécifiez pas -type f find trouvera également la liste des répertoires que vous ne souhaitez peut-être pas.


Ou une solution plus générale utilisant la combinaison très utile find | xargs:

find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm --

par exemple, supprimez tous les fichiers non txt du répertoire en cours:

find . -type f -not -name '*txt' -print0 | xargs -0 rm --

Les combinaisons print0 et -0 sont nécessaires s'il existe des espaces dans l'un des noms de fichiers à supprimer.

209
awi
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)

L'extglob (Extended Pattern Matching) doit être activé dans BASH (s'il n'est pas activé):

shopt -s extglob
148
pl1nk

find . | grep -v "excluded files criteria" | xargs rm

Ceci listera tous les fichiers du répertoire courant, puis tous ceux qui ne correspondent pas à vos critères (méfiez-vous des noms de répertoire correspondants), puis supprimez-les.

Mise à jour: en fonction de votre modification, si vous voulez vraiment tout supprimer du répertoire courant à l’exception des fichiers que vous avez énumérés, vous pouvez l’utiliser:

mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup

Il créera un répertoire de sauvegarde /tmp_backup (vous avez les privilèges root, non?), Déplacez les fichiers que vous avez répertoriés vers ce répertoire, supprimez récursivement tout le contenu du répertoire en cours (vous savez que vous êtes dans le bon répertoire, vous?), retournez au répertoire courant de /tmp_backup et finalement, supprimez /tmp_backup.

J'ai choisi le répertoire de sauvegarde à la racine, car si vous essayez de tout supprimer de manière récursive, votre système aura de gros problèmes.

Il existe sûrement des moyens plus élégants de le faire, mais celui-ci est assez simple.

40
darioo

Vous pouvez utiliser la variable d’environnement GLOBIGNORE dans Bash.

Supposons que vous souhaitiez supprimer tous les fichiers sauf php et sql, vous pouvez alors procéder comme suit:

export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=

Définir GLOBIGNORE comme ceci ignore php et sql des caractères génériques utilisés tels que "ls *" ou "rm *". Donc, utiliser "rm *" après avoir défini la variable ne supprimera que les fichiers txt et tar.gz.

19
theharshest

En supposant que les fichiers portant ces noms existent à plusieurs endroits dans l'arborescence de répertoires et que vous souhaitez les conserver tous:

find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
18
Dennis Williamson

Je préfère utiliser la liste de sous-requête:

rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`

-v, --invert-match sélectionne des lignes non concordantes

\| Séparateur

16
Nick Tsai

Puisque personne n'en a parlé:

  • copier les fichiers que vous ne voulez pas supprimer dans un endroit sûr
  • supprimer tous les fichiers
  • remet les fichiers copiés en place
9
gniourf_gniourf

Un peu en retard pour l'OP, mais j'espère utile pour tous ceux qui arriveront bien plus tard par google ...

J'ai trouvé la réponse de @awi et les commentaires sur -delete de @Jamie Bullock vraiment utiles. Un utilitaire simple vous permettant de le faire dans différents répertoires en ignorant à chaque fois différents noms/types de fichiers avec un minimum de frappe:

rm_except (ou le nom de votre choix)

#!/bin/bash

ignore=""

for fignore in "$@"; do
  ignore=${ignore}"-not -name ${fignore} "
done

find . -type f $ignore -delete

par exemple. tout supprimer sauf les fichiers texte et foo.bar:

rm_except *.txt foo.bar 

Similaire à @mishunika, mais sans la clause if.

6
CaptainKinematics

Vous pouvez écrire une boucle for pour cela ...%)

for x in *
do
        if [ "$x" != "exclude_criteria" ]
        then
                rm -f $x;
        fi
done;
6
mishunika

Si vous utilisez zsh , je le recommande vivement.

rm -rf ^file/folder pattern to avoid

Avec extended_glob

setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
5
sudo bangbang

L'essayer a fonctionné avec:

rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)

mais les noms avec des espaces sont (comme toujours) difficiles. Essayé aussi avec Virtualbox\ VMs à la place des guillemets. Il supprime toujours ce répertoire (Virtualbox VMs).

4
juanfal

Juste:

rm $(ls -I "*.txt" ) #Deletes file type except *.txt

Ou:

rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
4
wyx

Rendre les fichiers immuables. Même root ne sera pas autorisé à les supprimer.

chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *

Tous les autres fichiers ont été supprimés.
Vous pouvez éventuellement les réinitialiser.

chattr -i *
1

Vous pouvez le faire avec deux séquences de commandes. Commencez par définir un tableau avec le nom des fichiers que vous ne souhaitez pas exclure:

files=( backup.tar.gz script.php database.sql info.txt )

Après cela, parcourez tous les fichiers du répertoire que vous souhaitez exclure, en vérifiant si le nom du fichier se trouve dans le tableau que vous ne souhaitez pas exclure; sinon, supprimez le fichier.

for file in *; do
  if [[ ! " ${files[@]} " ~= "$file"  ]];then
    rm "$file"
  fi
done
0
Leonardo Hermoso

Ceci est similaire au commentaire de @ siwei-shen mais vous avez besoin de l'indicateur -o pour créer plusieurs motifs. Le drapeau -o signifie "ou"

find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm

0
Daniel Chen