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
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
Réponses:
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
-delete
ainsi que quels fichiers seront enregistrés en supprimant -delete
et le \!
.
find
c'est récursif! de sorte que tous les sous-répertoires de fichiers ne correspondant pas au « modèle » seront également supprimés
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.
Les versions ultérieures de bash ont l' extglob
option 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 rm
par echo
pour voir si la liste des fichiers à supprimer est celle que vous attendez.
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
a
, b
et a b
le premier programme supprimera - si vous mettez ab dans la partie grep: "^[ab]$"
a
et b
non 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.
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.
/
, hein? Pas très pratique. c) Essayer de supprimer tous les fichiers de votre $HOME
n'est pas vraiment pratique non plus.
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
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
find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -delete
est une façon de contourner ce problème.
tmp
s'il n'y avait pas de fichiers X
/ Y
/ Z
. Remarque !
comme l'équivalent standard de GNU -not
( -delete
est également une extension GNU)