Co oznacza [co] w komendzie „rm -rf nazwa pliku [co]”?

16

Załóżmy, że mam dwa pliki /tmp:

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

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

Teraz uruchommy rm -rfpolecenie z opcją [co]

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

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

Czy ktoś może wyjaśnić, co się tutaj dzieje? Jaki jest [co]parametr? Jak możemy sprawić, by działał dla innych rozszerzeń? Powiedzmy mam foo.jsi foo.coffeepliki, możemy zrobić coś rm -rf /tmp/foo.coffe[co], aby usunąć /tmp/foo.js?

aneeshep
źródło
8
Nie ma takiej potrzeby -rf, ponieważ nie są to ani katalogi ( --recursive), ani niezaprzeczalne ( --force).
deltab
13
Nie ma takiej potrzeby -rfi nie trzeba robić rzeczy jako root. Zwłaszcza jeśli chodzi o te rzeczy rm -rf.
terdon
Chłopaki, to tylko przykładowe polecenia wyjaśniające problem. Właściwe pytanie dotyczyło [co]powłoki glob. Dzięki.
aneeshep
8
@aneeshep Jeśli ktoś patrzy w dół na lufę pistoletu i pyta, jak go wyczyścić, czy najpierw ostrzegasz go, aby nie patrzył w dół na lufę, czy mówisz, jak to wyczyścić?
Duncan X Simpson

Odpowiedzi:

34

[co]Nie jest to parametr do rmkomendy - to glob shell , który pasuje do wzorca równa jeden znak ze zbioru [co]- innymi słowy, pasuje zarówno do calbo odo końca pliku. Od man bash:

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

Aby dopasować oba, foo.coffeea foo.jsponieważ sufiksy nie zawierają w ogóle żadnych wspólnych podciągów, najlepiej jest foo.*dopasować dowolną nazwę pliku zaczynającą się od foo.Zamiast tego można użyć rozszerzenia nawiasów np.

rm foo.{coffee,js}
steeldriver
źródło
Tak, rozumiem. Brakowało mi podstawowej koncepcji bash;). Dziękuję :)
aneeshep,
7
wzorce wyszukiwania takie jak [abc]lub *będą wyszukiwać pliki, podczas gdy {}nie będą. przejdź do / tmp, wpisz echo nya[ab]; echo nya{a,b}, potem touch nyaai znowuecho nya[ab]; echo nya{a,b}
Sanya_Zol
16

To nie jest parametr, ale zbiór liter (lub „glob globu”). To jest to samo:

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

jest taki sam jak

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

Podobne ...

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

usunie cokolwiek z następujących po kolejności ASCII /tmp/hello.pycwłącznie /tmp/hello.pyo.

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

usunąłby ...

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

powiedzmy, że mam pliki foo.js i foo.coffee, czy możemy zrobić coś takiego jak rm -rf /tmp/foo.coffe[co]usunięcie pliku /tmp/foo.js.

Możesz tworzyć dość fantazyjne metody, ale dla tych 2 plików po prostu usunę je za pomocą jednego polecenia dla każdego. Kolejny przykład zbliżenia się do tych 2 plików ...

rm /tmp/foo.[cj]*

usuną takie pliki ...

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

więc zawierałby znacznie więcej niż tylko te 2 pliki.

Rinzwind
źródło
2
Jeśli się nie mylę, otrzymujesz jedno wywołanie rm -rfze wszystkimi dopasowaniami, a nie wiele wywołań z każdym dopasowaniem.
1
tak. ale nie zamiar rm dodałem. te mają tylko pokazać, co trzeba by wpisać jako odpowiednik ;-)
Rinzwind
1

To glob powłoki, podobny do symboli wieloznacznych *i ?... w bash, wzorzec nazw plików *.[co]pasuje do wszystkich nazw plików, które kończą się na .club .o.

Różnica w *.[co]porównaniu z *.c *.olub *.{c,o}polega na tym, że dwa ostatnie wzorce rozwiną się w atrapę, *.ojeśli .ow katalogu nie będzie żadnych plików, a *.[co]wersja nie.

Globusy powłoki są przydatne do wykonywania operacji na plikach bez rozróżniania wielkości liter. Na przykład, jeśli masz kilka pliki, które kończą się jpg, JPG, Jpg, JPg, etc ... i chcesz usunąć wszystkie z nich można zrobić:

rm *.[Jj][Pp][Gg]
delt
źródło