Natknąłem się na wzory globowania i symbole wieloznaczne, a szczególnie mnie interesuje [!]
.
Konstrukcja ta jest podobna do
[!]
konstrukcji, z wyjątkiem tego, że zamiast dopasowywać dowolne znaki w nawiasach, będzie pasować do dowolnego znaku, o ile nie będzie wymieniony między[
a]
.
rm myfile [!192]
Powyższe wierzę, że usunie wszystkie / wszystkie pliki, z wyjątkiem jakichkolwiek / wszystkich plików, które mają 192 w nazwie.
Niepokoi mnie jednak prawidłowe użycie tego rozszerzenia pliku, aw szczególności wielu warunków.
Jaka byłaby właściwa składnia w takiej sytuacji?
rm myfile [!.gif .csv. mp3]
lub
rm myfile [!.gif !.csv !.mp3]
Martwię się, że kropka może zostać zgubiona, a więc każdy plik z .
(który z nich by był na pewno?) Zostałby zmanipulowany, gdy chcę spowodować manipulację konkretnymi plikami.
Konstrukcja ta jest podobna do [ ]
konstrukcji, z wyjątkiem tego, że zamiast dopasowywać dowolne znaki w nawiasach, będzie pasować do dowolnego znaku, o ile nie będzie wymieniony między [
a ]
.
(cytowany z http://www.tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm )
Teraz; dla mnie, co sugeruje, że liczba pojedyncza !
jest wystarczająca, a wszystkie wartości w nim zawarte są zawarte w zakresie.
źródło
ls my-pattern
lub,echo my-command
aby sprawdzić, czy globowanie jest wykonywane tak, jak chcesz, przed uruchomieniemrm
[!]
jest podobny, ale nie taki[!]
^
ma dokładnie to samo znaczenie, co!
w tym kontekście, dlatego[^a]
wykluczaa
dokładnie tak, jak[!a]
robi: Jeśli pierwszy znak następujący po [jest! lub ^, dopasowywany jest dowolny znak nie dołączony. (man bash
)rm myfile [!192]
usuniemyfile
, a także każdy plik jednoznakowy1
, który nie ma nazwy9
, lub2
.Odpowiedzi:
Powołując się
man 7 glob
:Nacisk na pojedynczej postaci części tutaj,
[]
nie mogą być wykorzystywane do całych ciągów w bash Pattern Matching.bash
„s Brace rozszerzeń mogą być używane w celu dopasowania ciągów, jednak nie ma możliwości (wiem), aby je negować. Na przykładjest rozwinięty do
bez względu na to, czy te pliki istnieją.
Jak wskazano wchargin ,
shopt
można użyć operatorów rozszerzonego dopasowywania wzorców, z których jednym jest!()
. Po uruchomieniushopt -s extglob
npjest rozwinięty do
jeśli te pliki istnieją w bieżącym katalogu. Więcej informacji można znaleźć
man bash
(sekcja ROZSZERZENIE / Rozszerzenie nazwy ścieżki) i Rozszerzenie nazwy ścieżki (globbing) .Do tego, co próbujesz zrobić, zawsze używałbym
find
, co oferuje negację i wiele więcej, np. W następujący sposób:To tylko lista ustaleń, jeśli chcesz je usunąć, po prostu dołącz
-delete
opcję na końcu polecenia. Jak zawsze przy usuwaniu czynności: zawsze najpierw sprawdź dokładnie .find
oferuje mnóstwo przydatnych opcji bardzo dobrze wyjaśnionych przezman find
.źródło
find
polecenie jest rekurencyjne ( edytuj: jak pierwotnie pokazano - mogę zachować ten komentarz dla dodatkowych istotnych, ale nieistotnych informacji, które przekazuje). Aby znaleźć pliki znajdujące się tylko w bieżącym katalogu, ale nie także w jego podkatalogach - a zatem usuń te pliki tylko, jeśli-delete
akcja zostanie dodana - możesz dodać-maxdepth 1
natychmiast pofind .
. Spowodowałoby to dostosowanie go do efektu globowania, ponieważ globsy nie są rekurencyjne w Bash, chyba żeglobstar
opcja powłoki jest włączona i**
używana. Glob pokazany w pytaniu nie jest rekurencyjny we wszystkich powłokach.shopt -s extglob
, można użyćecho 1.!(gif|csv|mp3)
, która drukuje wszystko1.ext
, gdzieext
nie jestgif
,csv
albomp3
. (Zobacz podsekcję „Dopasowywanie wzorców”man bash
.)Myślę, że źle zrozumiałeś użycie nawiasów.
[abc]
dopasowuje jeden z bohaterówa
,b
lubc
.[!abc]
dopasowuje jeden znak, który nie jesta
,b
lubc
. Więc rozkazusunie
myfile
i pliki1
,9
a2
ponieważ masz przestrzeń pomiędzy myfile i wspornika. W przeciwieństwie do poleceniausunie pliki
myfile1
,myfile9
amyfile2
.źródło
find
.Nawiasy
[
]
oznaczają klasę postaci. Dowolny pojedynczy znak w nich może pasować na danej pozycji. Więcpasuje do trzech możliwych nazw:
To nie nie pasuje
file192
, ponieważ dotyczy on tylko z jednego znaku pofile
.Możemy również używać zakresów w nawiasach.
[0-9]
dopasowuje dowolną pojedynczą cyfrę na danej pozycji. Potrzebujemy dwóch cyfr[0-9][0-9]
. W przypadku cyfry, po której następuje wielka litera, moglibyśmy użyć[0-9][A-Z]
...!
wskazuje na negację.dopasuje pliki, które mają dowolny pojedynczy znak po
file
wyjątkiem1
lub9
lub2
. Na przykład będzie pasowaćfile7
ifiles
afile%
(i wiele innych), ale niefile192
, dlatego, że posiada dwa dodatkowe znaki.W twoim przypadku sugeruję użycie
find
zamiast[!]
. Manot
operatora.Jest również rekurencyjny , co oznacza, że domyślnie przechodzi do wszystkich podkatalogów. Możesz ograniczyć go do bieżącego katalogu za pomocą
-maxdepth 1
, jeśli tego chcesz. Symbole wieloznaczne powłoki (globbing) nie są rekurencyjne (chociaż**
można włączyć globalne rekurencyjne z ).Zakładając, że nie chcesz unikać usuwania dowiązań symbolicznych, możemy dodać
-type d
do zanegowanych testów, aby uniknąć usuwania katalogów. Dzięki Eliahowi Kaganowi za tę sugestię.Jeśli zobaczysz, co chcesz, możesz ponownie uruchomić polecenie za pomocą
-delete
źródło
[0-9a-fA-F]