Que signifie [co] dans la commande «rm -rf filename [co]»?

16

Disons que j'ai deux fichiers dans /tmp:

root@ubuntu:~# touch /tmp/hello.{pyc,py}

root@ubuntu:~# ls /tmp/
hello.py  hello.pyc

Maintenant, permet d'exécuter la rm -rfcommande avec l'option [co]

root@ubuntu:~# rm -rf /tmp/hello.py[co]

root@ubuntu:~# ls /tmp/
hello.py

Quelqu'un peut-il expliquer ce qui se passe ici? Quel est le [co]paramètre? Comment pouvons-nous le faire fonctionner pour d'autres extensions? Dire que j'ai foo.jset foo.coffeefichiers, pouvons - nous faire quelque chose comme rm -rf /tmp/foo.coffe[co]de supprimer le /tmp/foo.js?

aneeshep
la source
8
Il n'y en a pas besoin -rf, car ce ne sont ni des répertoires ( --recursive), ni des caractères non inscriptibles ( --force).
deltab
13
Il n'est pas nécessaire -rfet il n'est pas nécessaire de faire les choses en tant que root. Surtout si les choses en question impliquent rm -rf.
terdon
Les gars, ses exemples de commandes pour expliquer le problème. La vraie question concernait le [co]shell glob. Merci.
aneeshep
8
@aneeshep Si quelqu'un regarde le canon d'un pistolet et demande comment le nettoyer, le prévenez-vous d'abord de regarder le canon ou lui dites-vous comment le nettoyer?
Duncan X Simpson

Réponses:

34

[co]n'est pas un paramètre de la rmcommande - c'est un glob de shell qui correspond à un modèle égal à un seul caractère de l'ensemble [co]- en d'autres termes, il correspond à a cou à ola fin du nom de fichier. De man bash:

[...]  Matches any one of the enclosed characters

Pour faire correspondre les deux foo.coffeeet foo.js, comme les suffixes ne contiennent aucune sous-chaîne commune, le mieux que vous puissiez faire est de faire foo.*correspondre n'importe quel nom de fichier commençant par À la foo.place, vous pouvez utiliser l' expansion d'accolade, par exemple

rm foo.{coffee,js}
tournevis
la source
Yup l'a compris. J'ai raté le concept de base en bash;). Merci :)
aneeshep
7
recherche des modèles comme [abc]ou *va rechercher des fichiers tout {}ne sera pas. allez dans / tmp, tapez echo nya[ab]; echo nya{a,b}, puis touch nyaaet encoreecho nya[ab]; echo nya{a,b}
Sanya_Zol
16

Ce n'est pas un paramètre mais une collection de lettres (ou un "shell glob"). C'est pareil:

rm -rf /tmp/hello.py[co]

est le même que

rm -rf /tmp/hello.pyc
rm -rf /tmp/hello.pyo

Similaire ...

rm -rf /tmp/hello.py[c-o]

supprimerait quoi que ce soit de /tmp/hello.pycjusqu'à et y compris/tmp/hello.pyo commande ASCII suivante.

rm -rf /tmp/hello.py[ab][cd]

supprimerait ...

rm -rf /tmp/hello.pyac
rm -rf /tmp/hello.pyad
rm -rf /tmp/hello.pybc
rm -rf /tmp/hello.pybd

disons que j'ai des fichiers foo.js et foo.coffee, pouvons-nous faire quelque chose comme rm -rf /tmp/foo.coffe[co] supprimer le/tmp/foo.js .

Vous pouvez créer des méthodes plutôt sophistiquées, mais pour ces 2 fichiers, je les supprimerais simplement avec 1 commande pour chacun. Un autre exemple se rapprochant le plus possible de ces 2 fichiers ...

rm /tmp/foo.[cj]*

supprimerait des fichiers comme celui-ci ...

rm /tmp/foo.c*
rm /tmp/foo.j*

il comprendrait donc bien plus que ces 2 fichiers.

Rinzwind
la source
2
Si je ne me trompe pas, vous obtenez une invocation de rm -rftoutes les correspondances, pas beaucoup d'invocations chacune avec une correspondance.
1
Oui. mais pas l'intention du rm's i ajouté. ce sont juste pour montrer ce qui serait nécessaire pour être tapé comme équivalent ;-)
Rinzwind
1

C'est un glob de shell, similaire aux caractères génériques *et ?... en bash, le modèle de nom de fichier *.[co]correspond à tous les noms de fichiers qui se terminent par .cou .o.

La différence avec *.[co]versus *.c *.oou *.{c,o}est que les deux derniers modèles se développeront en un faux *.osi aucun .ofichier n'existe dans le répertoire, alors que la *.[co]version ne le fera pas.

Les globes shell sont utiles pour effectuer des opérations sur les fichiers sans respecter la casse. Par exemple, si vous avez un tas de fichiers avec des noms qui se terminent par jpg, JPG, Jpg, JPg, etc ... et que vous voulez supprimer tous, vous pouvez le faire:

rm *.[Jj][Pp][Gg]
delt
la source