utiliser rm pour supprimer les fichiers et répertoires de manière récursive

17

est-il possible d'utiliser rm pour supprimer les fichiers et répertoires correspondant à un modèle de manière récursive sans utiliser d'autres commandes?

user15586
la source

Réponses:

35

Pour répondre directement à votre question, "non - vous ne pouvez pas faire ce que vous décrivez rm".

Vous pouvez cependant le faire en le combinant find. Voici l'une des nombreuses façons de procéder:

 # search for everything in this tree, search for the file pattern, pipe to rm
 find . | grep <pattern> | xargs rm

Par exemple, si vous souhaitez supprimer tous les fichiers * ~, vous pouvez donc ceci:

 # the $ anchors the grep search to the last character on the line
 find . -type f | grep '~'$ | xargs rm

Pour développer à partir d'un commentaire * :

 # this will handle spaces of funky characters in file names
 find -type f -name '*~' -print0 | xargs -0 rm
garenne
la source
1
vrai - si vous omettez la dernière pipe, vous obtiendrez une liste de tout d'abord :)
warren
2
Peut ne pas répondre directement à la question de l'affiche, mais est le plus proche de ce qu'il veut.
Drakia
1
Un nain, n'est-ce pas un peu amer sans raison?
Gnoupi
10
Veuillez être très prudent lors de l'utilisation find | grep | xargs rm. S'il y a des fichiers avec des espaces (ou des nouvelles lignes), cela se cassera (et selon les noms de fichiers et l'emplacement des espaces) pourrait supprimer des éléments que vous n'aviez pas l'intention de supprimer. find … -print0 | xargs -0 rmsera beaucoup plus robuste. Cela signifie cependant que vous ne pouvez pas utiliser grepet devez utiliser findles prédicats de pour faire correspondre et imprimer uniquement les fichiers souhaités. le deuxième exemple de warren sera plus robuste que find -type f -name '*~' -print0 | xargs -0 rm.
Chris Johnsen
1
Si vous souhaitez qu'une seule commande fasse le travail, créez un alias à l'aide de l'une des commandes find fournies. Remplira une réponse pour cela plus tard, si vous le souhaitez.
casualuser
8

"sans utiliser d'autres commandes"

Non.

Drakia
la source
Belle réponse illustrant le débat "répondre strictement à la question initiale (au risque de ne pas pouvoir apporter de solution)" vs "proposer une solution, même si elle ne correspond pas strictement aux restrictions imposées".
Gnoupi
J'ai seulement posté ceci car "Un nain" se plaignait de la réponse qui a réellement fourni une solution. Sans utiliser d'autres commandes, il n'y a vraiment aucun moyen de supprimer un fichier récursivement qui correspond à un modèle, juste la suppression du fichier / répertoire du répertoire courant.
Drakia
3

En utilisant Bash, avec globstarset, oui :

rm basedir/**/my*pattern*

Essayez-le avec, par exemple, d' ls -1abord, avant rmde répertorier les fichiers que vous correspondez.

Vous définissez les options par exemple shopt -s globstar.


Alternativement, une findvariante plus courte :

find -type f -name 'my*pattern*' -delete

ou pour GNU find:

find -type f -name 'my*pattern*' -exec rm {} +

ou une autre alternative pour non-GNU find(un peu plus lent):

find -type f -name 'my*pattern*' -exec rm {} \;

Pour supprimer également les répertoires, comme vous le demandez: changez simplement rmen rm -rdans les commandes ci-dessus et ignorez la correspondance uniquement -type fdans les findcommandes.

Daniel Andersson
la source
0

J'aurais aspiré "rm -rf" où se trouve une combinaison de noms de fichiers et de modèles correspondants tels que * et? etc (par exemple todays_log_2009 ????. log). Cela commencera à partir du répertoire actuel et diminuera de manière récursive les fichiers qui correspondent à ce modèle.

ianfuture
la source
Cela ne fonctionnera pas car le modèle est développé par le shell dans le répertoire courant. S'il est cité, le modèle devient un nom de fichier contenant des caractères spéciaux. par exemple pour supprimer le fichier [, on pourrait écrire rm '['. Le motif perd tout simplement son sens.
casualuser
0

Si vous utilisez zsh (1) , activez "extension globale" avec setopt extendedglobdans .zshrc. Préfixer le motif avec '** /' supprimera alors récursivement:

% rm -rf ** / <modèle>

Cependant, s'il y a beaucoup de fichiers à supprimer, vous devez recourir à find (1) avec xargs (1) ou -exec, et je recommande également de le faire dans les scripts shell.

kaleissin
la source