Это является домашним заданием вопроса:
Сопоставьте все имена файлов с 2 или более символами, которые начинаются со строчной буквы, но не заканчиваются заглавной буквой.
Я не понимаю, почему мое решение не работает.
Поэтому я выполнил следующее:
touch aa
touch ha
touch ah
touch hh
touch a123e
touch hX
touch Ax
ls [a-z]*[!A-Z]
Вывод:
aa ha
Мой вопрос: почему он не соответствует "ах", "чч" или "a123e"?
mksh
оболочкой, но нетbash --posix
, так что должно быть какое-то определенное правило для bash`mksh
напримерzsh
, лайки[A-Z]
не совпадаютÉ
. ksh93 в[A-Z]
матчах наÉ
но не наh
.Ответы:
Это проблема локали . В вашей локали
[A-Z]
расширяется до чего-то вроде[AbBcZ...zZ]
(плюс, вероятно, другие, например, акцентированные символы), поэтому[^A-Z]
фактически означает «файлы, которые заканчиваютсяa
» в вашем примере (и только в вашем примере).Если вы хотите избежать такого сюрприза, установите один из способов,
LC_COLLATE=C
поскольку параметры сортировки - это часть настроек вашего языка, которая отвечает за порядок сортировки. Кроме того, пусто,LC_ALL
если оно установлено, так как оно будет иметь приоритет.Или, что лучше, вероятно, предпочтительнее не менять настройки локали и использовать соответствующие классы:
[:lower:]
вместо[a-z]
и[:upper:]
вместо[A-Z]
.Или используйте
globasciiranges
опцию bash :источник
LC_ALL=C ls [a-z]*[^A-Z]
влияет только наls
локаль, а не на локаль, используемую оболочкой для расширения глобуса или анализа этой командной строки.LC_xxx
его, чтобы применить к глобу, но это было бы предпочтительнее, поэтому ls получает ту же локаль.test-鏏
например, потому что, как только вы измените кодировку на кодировку для локали C, она鏏
станет<0xe7>A
. Итак, при изменении LC_CTYPE вы получаете разные символы.é
,Á
(но , вероятно , неŹ
). IOW, использование[A-Z]
имеет мало смысла вне языка Си.