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
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.
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
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.
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.
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
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
Puisque personne n'en a parlé:
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.
Vous pouvez écrire une boucle for pour cela ...%)
for x in *
do
if [ "$x" != "exclude_criteria" ]
then
rm -f $x;
fi
done;
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)
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
).
Juste:
rm $(ls -I "*.txt" ) #Deletes file type except *.txt
Ou:
rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
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 *
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
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