Ve všech shellech, které znám, rm [A-Z]* odstraní všechny soubory, které začínají velkým písmenem, ale s bash to odstraní všechny soubory, které začínají písmenem.
Protože tento problém existuje na Linuxu a Solarisu s bash-3 a bash-4, nemůže to být chyba způsobená chybným porovnáváním vzorů v knihovně libc nebo chybně nakonfigurovanou definicí národního prostředí.
Je toto podivné a riskantní chování zamýšleno nebo je to jen chyba, která existuje již mnoho let neopravená?
Přijatá odpověď:
Pamatujte, že při použití výrazů rozsahu jako [a-z] mohou být v závislosti na nastavení LC_COLLATE zahrnuta i jiná písmena.
LC_COLLATE je proměnná, která určuje pořadí řazení použité při třídění výsledků rozšíření názvu cesty a určuje chování výrazů rozsahu, tříd ekvivalence a porovnávacích sekvencí v rámci rozšíření názvu cesty a porovnávání vzorů.
Zvažte následující:
$ touch a A b B c C x X y Y z Z
$ ls
a A b B c C x X y Y z Z
$ echo [a-z] # Note the missing uppercase "Z"
a A b B c C x X y Y z
$ echo [A-Z] # Note the missing lowercase "a"
A b B c C x X y Y z Z
Všimněte si, že příkaz echo [a-z] zavoláno, očekávaným výstupem budou všechny soubory s malými písmeny. Také s echo [A-Z] , lze očekávat soubory s velkými písmeny.
Standardní řazení s národními prostředími, jako je en_US mají následující pořadí:
aAbBcC...xXyYzZ
- Mezi
aaz(v[a-z]) jsou VŠECHNA velká písmena, kroměZ. - Mezi
AaZ(v[A-Z]) jsou VŠECHNA malá písmena, kroměa.
Viz:
aAbBcC[...]xXyYzZ
| |
from a to z
aAbBcC[...]xXyYzZ
| |
from A to Z
Pokud změníte LC_COLLATE proměnná na C vypadá to podle očekávání:
$ export LC_COLLATE=C
$ echo [a-z]
a b c x y z
$ echo [A-Z]
A B C X Y Z
Takže to není chyba , je to problém s řazením .
Místo výrazů rozsahu můžete použít třídy znaků definované v POSIX, jako je upper nebo lower . Pracují také s různými LC_COLLATE konfigurace a dokonce i s znaky s diakritikou :
$ echo [[:lower:]]
a b c x y z à è é
$ echo [[:upper:]]
A B C X Y Z