web-dev-qa-db-fra.com

Comment supprimer plusieurs fichiers à la fois dans Bash sous Linux?

J'ai cette liste de fichiers sur le serveur Linux:

abc.log.2012-03-14
abc.log.2012-03-27
abc.log.2012-03-28
abc.log.2012-03-29
abc.log.2012-03-30
abc.log.2012-04-02
abc.log.2012-04-04
abc.log.2012-04-05
abc.log.2012-04-09
abc.log.2012-04-10

Je supprime les fichiers journaux sélectionnés un par un à l'aide de la commande rm -rf (voir ci-dessous):

rm -rf abc.log.2012-03-14 
rm -rf abc.log.2012-03-27
rm -rf abc.log.2012-03-28

Existe-t-il un autre moyen de supprimer les fichiers sélectionnés en une fois??

94
user1253847

Bash prend en charge toutes sortes de jokers et de développements.

Votre cas exact serait traité par extension d'accolade , comme ceci:

$ rm -rf abc.log.2012-03-{14,27,28}

Ce qui précède développerait une () = commande unique avec les trois arguments, et équivaudrait à taper:

$ rm -rf abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28

Il est important de noter que cette expansion est effectuée par le shell, avant même que rm ne soit chargé.

148
unwind

Utilisez un caractère générique (*) pour faire correspondre plusieurs fichiers.

Par exemple, la commande ci-dessous supprimera tous les fichiers dont le nom commence par abc.log.2012-03-.

rm -f abc.log.2012-03-*

Je vous recommande d'exécuter ls abc.log.2012-03-* pour répertorier les fichiers de manière à voir ce que vous allez supprimer avant d'exécuter la commande rm.

Pour plus de détails, voir la page de manuel Bash sur extension du nom de fichier .

72
dogbane

Si vous souhaitez supprimer tous les fichiers dont les noms correspondent à un formulaire particulier, un caractère générique (modèle global) est la solution la plus simple. Quelques exemples:

$ rm -f abc.log.*             # Remove them all
$ rm -f abc.log.2012*         # Remove all logs from 2012
$ rm -f abc.log.2012-0[123]*  # Remove all files from the first quarter of 2012

Les expressions régulières sont plus puissantes que les caractères génériques; vous pouvez alimenter la sortie de grep en rm -f. Par exemple, si certains noms de fichiers commencent par "abc.log" et d'autres par "ABC.log", grep vous permet de faire une correspondance insensible à la casse:

$ rm -f $(ls | grep -i '^abc\.log\.')

Lorsque je le fais, j’exécute d’abord la commande ls | grep ... et vérifie qu’elle produit le résultat souhaité - en particulier si j’utilise rm -f:

$ ls | grep -i '^abc\.log\.'
(check that the list is correct)
$ rm -f $(!!)

!! passe à la commande précédente. Ou je peux taper la flèche vers le haut ou Ctrl-P et éditer la ligne précédente pour ajouter la commande rm -f.

Cela suppose que vous utilisez le shell bash. Certains autres shells, en particulier csh et tcsh, ainsi que certains anciens shells dérivés de sh, peuvent ne pas prendre en charge la syntaxe $(...). Vous pouvez utiliser la syntaxe de backtick équivalente:

$ rm -f `ls | grep -i '^abc\.log\.'`

La syntaxe $(...) est plus facile à lire et, si vous êtes vraiment ambitieux, elle peut être imbriquée.

Enfin, si le sous-ensemble de fichiers que vous souhaitez supprimer ne peut pas être facilement exprimé avec une expression régulière, une astuce que j'utilise souvent consiste à répertorier les fichiers dans un fichier texte temporaire, puis à le modifier:

$ ls > list
$ vi list   # Use your favorite text editor

Je peux ensuite éditer le fichier list manuellement, en ne laissant que les fichiers que je veux supprimer, puis:

$ rm -f $(<list)

ou

$ rm -f `cat list`

(Cela suppose qu'aucun des noms de fichier ne contient de caractères amusants, en particulier des espaces.)

Ou, lors de l'édition du fichier list, je peux ajouter rm -f au début de chaque ligne, puis:

$ . ./list

ou

$ source ./list
36
Keith Thompson

Utilisez simplement multiligne selection en sublime pour combiner tous les fichiers en une seule ligne, ajoutez un espace entre chaque nom de fichier, puis ajoutez rm au début de la liste. Ceci est surtout utile quand il n'y a pas de motif dans les noms de fichiers que vous voulez supprimer.

[$]> rm abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 abc.log.2012-03-29 abc.log.2012-03-30 abc.log.2012-04-02 abc.log.2012-04-04 abc.log.2012-04-05 abc.log.2012-04-09 abc.log.2012-04-10
8
Andy

Un wild card fonctionnerait bien pour cela, bien que pour des raisons de sécurité, il serait préférable de rendre l'utilisation du wild card aussi minime que possible.

rm -rf abc.log.2012-*

Bien que, apparemment, ce ne soient que des fichiers simples? L'option récursive ne devrait pas être nécessaire si aucun de ces éléments n'est un répertoire, il est donc préférable de ne pas l'utiliser, pour des raisons de sécurité.

5
lacrosse1991

Je ne suis pas un gourou Linux, mais je crois que vous souhaitez diriger votre liste de fichiers de sortie vers xargs rm -rf. J'ai utilisé quelque chose comme ça dans le passé avec de bons résultats. Testez d'abord sur un exemple de répertoire!

EDIT - J'ai peut-être mal compris en me basant sur les autres réponses qui apparaissent. Si vous pouvez utiliser des caractères génériques, c'est parfait. J'ai supposé que la liste originale que vous aviez affichée avait été générée par un programme qui vous donnait votre "sélection". Je pensais donc que le cheminement vers xargs serait la solution.

2
Dave