Zwykle w globowaniu bash rozróżniana jest wielkość liter:
$ echo c*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo C*
CarePackage.md ChocRippleCake.md Clips
Używanie nawiasów kwadratowych nie zmienia tego:
$ echo [c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C]*
CarePackage.md ChocRippleCake.md Clips
Nadal nie zmienia tego, jeśli używany jest łącznik:
$ echo [c-c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C-C]*
CarePackage.md ChocRippleCake.md Clips
Ale litery są przeplatane:
$ echo [B-C]*
CarePackage.md casefix.pike cdless chalices.py charconv.py chocolate.pike ChocRippleCake.md circum.py clip.pike Clips cpustats.pike crop.pike cwk2txt.py
$ echo [b-c]*
beehive-anthem.txt bluray2mkv.pike branch branchcleanup.pike burdayim.pike casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
Sugeruje to, że łącznik używa kolejności ustawień regionalnych „AaBbCcDd”. Więc: czy istnieje sposób globowania dla wszystkich plików, które zaczynają się od dużej litery?
[A-Z]
pasują małe litery w bash?Odpowiedzi:
W wersji bash 4.3 i nowszych dostępna jest opcja shopt o nazwie
globasciiranges
:Według stron man wbudowanych w GNU :
W rezultacie możesz
Użyj
shopt -u
do wyłączenia.Innym sposobem jest zmiana ustawień regionalnych na C. Możesz to zrobić tymczasowo za pomocą podpowłoki:
Otrzymasz potrzebne wyniki, a gdy skończona podpowłoka, ustawienia regionalne głównej powłoki pozostaną niezmienione w stosunku do tego, co było wcześniej.
Inną alternatywą jest zamiast
[A-Z]
używania nawiasów klamrowych{A..Z}
razem znullglob
opcją bash shopt.Po włączeniu
nullglob
opcji, jeśli wzorzec nie jest dopasowywany podczas rozwijania nazwy ścieżki, zwracany jest ciąg zerowy zamiast samego wzorca.W rezultacie ten będzie działał zgodnie z oczekiwaniami:
źródło
[[:upper:]]
bo tak naprawdę chcę tylko część alfabetu, ale to działa.man bash
w swoim terminalu i wyszukać (za pomocą/
) globasciiranges.LC_ALL=C printf '%s\n' [A-Z]*
działałoby w przypadku drugiego rozwiązania - bez podpowłoki? BTW: jest literówka:nullblog
ale jest za mało znaków, żeby to poprawić.Możesz pisać wszystkie wielkie litery, tak jak:
lub użyj może użyć nazwanej klasy znaków
[:upper:]
do przedstawienia wszystkich wielkich liter w twoim bieżącymlocale
:Jak zauważyłeś, przy użyciu zakresu, takiego jak
[B-C]
wielka i mała litera dla tego samego znaku alfabetu, układane są obok siebie (zgodnie z porządkiem sortowanialocale
).źródło
Włączanie „nieintuicyjnych” znaków w zakresach znaków, na przykład uwzględnianie małych liter w zakresie, którego granice są wielkimi literami, wynika z
LC_COLLATE
ustawienia regionalnego.LC_COLLATE
ma wskazywać kolejność sortowania, ale robi z tym kiepską robotę (sortowanie ciągów jest bardziej skomplikowane niż to, co mogą robić lokalizacje) i lepiej bez niego. Zalecam usunięcieLC_COLLATE
z ustawień regionalnych. Jeśli jesteś ustawienieLANG
, alboLANGUAGE
nie rób tego i ustawić tylko te potrzebne są:LC_CTYPE
,LC_MESSAGES
,LC_TIME
.Aby uzyskać więcej informacji na temat ustawień narodowych, zobacz Co należy ustawić w moich ustawieniach regionalnych i jakie są tego konsekwencje? i ustaw LC_ *, ale nie LC_ALL
Aby uzyskać wiarygodne wyniki w skrypcie niezależnie od ustawień użytkownika, ustaw
LC_ALL=C
.źródło
Zestaw:
Ze strony podręcznika użytkownika bash:
Jeśli ustawisz „globasciiranges”, nie wiem, co stanie się z postaciami nie-ascii, takimi jak utf-8
źródło
echo [cC] * powinno robić, co chcesz, podobnie [A-Za-z] *
Jestem tutaj, ponieważ globowanie w moim systemie właśnie przestało rozróżniać małe i wielkie litery, więc mnóstwo moich skryptów nie działa już tak, jak powinny :-(
źródło