Supprimer des fichiers sans chaîne dans le nom

9

Je souhaite supprimer les fichiers qui n'ont pas la chaîne «999» (sans le «») dans leur nom.

J'ai essayé:

grep -vlr 999 . | xargs -0 rm -f --
find . -print0 | grep --null-data -v 999 | xargs -0 rm --

Mais aucun ne fonctionne. J'utilise macOS Sierra, avec bash: 3.2.57.

plr
la source
2
grep -lle fait lister les fichiers où une correspondance a été trouvée (ou introuvable avec -v) dans le contenu , pas le nom de fichier. grepcorrespond toujours au contenu des fichiers que vous spécifiez, jamais à leurs noms.
JoL

Réponses:

18

Utilisation d'un modèle de globalisation étendu dans bash:

rm ./!(*999*)

Cela doit shopt -s extglobêtre activé (et pour des raisons de sécurité également shopt -s failglob, afin qu'aucun fichier portant le nom inhabituel ne !(*999*)soit supprimé par erreur si tous les noms de fichiers contiennent 999). Le modèle !(*999*)correspondra à n'importe quel nom du répertoire actuel, à l'exception des noms correspondants *999*. Pour supprimer également les fichiers cachés (fichiers dont le nom commence par un point ), activez également l' dotgloboption.

Pour ne vous soucier que des fichiers normaux ou des liens symboliques vers des fichiers normaux (pas des répertoires, etc.):

for name in ./!(*999*); do [ -f "$name" ] && rm "$name"; done

Le zshshell équivalent à la boucle ci-dessus serait

rm ./(^(*999*))(.)

Votre première commande ne fonctionnera pas puisqu'elle grepregardera à l'intérieur des fichiers. Il supprimerait tous les fichiers contenant des lignes sans 999(si vous aviez ajouté l' --nulloption pour que cela fonctionne avec xargs -0).

Votre deuxième commande ne fonctionnera pas car grepsur macOS ne prend pas en charge --null-data(elle a cependant une --nulloption, mais uniquement pour la génération de sortie de nom de fichier). Notez également qu'il rechercherait 999n'importe où dans le chemin du fichier (y compris les composants du répertoire), pas seulement le nom du fichier.

Kusalananda
la source
1
Vous voudriez également activer l' failgloboption ou cela pourrait finir par supprimer le fichier appelé !(*999*)s'il n'y a pas d'autre fichier dont le nom ne contient pas 999.
Stéphane Chazelas
16

Inversez simplement la condition de nom dans find:

find . -type f \! -name "*999*" 

Ajoutez -deleteou -exec rm {} +supprimez réellement les fichiers correspondants.

ilkkachu
la source
2
!est en sécurité bash.
Kusalananda