[A-Z]
in bash
сопоставляет все элементы сортировки (символы, но call также являются последовательностью символов, как Dsz
в венгерских локалях), которые сортируют после A
и сортируют до Z
. В вашем регионе, c
вероятно, сортирует между B и C.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort
a
A
á
b
B
c
C
Ç
z
Z
Ẑ
Так c
или z
будет соответствовать [A-Z]
, но не Ẑ
или a
.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ |
pipe> bash -c 'while IFS= read -r x; do case $x in [A-Z]) echo "$x"; esac; done'
A
á
b
B
c
C
Ç
z
Z
В локали C, порядок будет:
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | LC_COLLATE=C sort
A
B
C
Z
a
b
c
z
Ç
á
Ẑ
Так [A-Z]
будет соответствовать A
, B
, C
, Z
, но не Ç
и до сих пор не Ẑ
.
Если вы хотите сопоставить буквы верхнего регистра (в любом скрипте), вы можете использовать [[:upper:]]
вместо этого. Там нет встроенного способа, bash
чтобы соответствовать только заглавные буквы в латинском скрипте (за исключением перечисления их по отдельности).
Если вы хотите , чтобы соответствовать A
на Z
английском языке буквами без диакритики, вы можете использовать [A-Z]
или , [[:upper:]]
но в C
локали (предполагается , что данные не кодируются в наборах символов , таких как BIG5 или GB18030 , который имеет несколько символов , чья кодировка содержит кодировку этих букв) или список их индивидуально ( [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
).
Обратите внимание, что есть некоторые различия между оболочками.
For zsh
, bash -O globasciiranges
(странно названная опция, введенная в bash-4.3), schily-sh
и yash
, [A-Z]
совпадает с символами, чья кодовая точка находится между той из A
и той из Z
, так что будет эквивалентно поведению bash
в локали Си.
Для пепла, mksh и древних оболочек, таких же, как zsh
указано выше, но ограничено однобайтовыми символами. То есть, например, в локали UTF-8 [É-Ź]
не будет совпадать Ó
, но так как [<c3><89>-<c5><b9>]
это будет соответствовать байтовым значениям от 0x89 до 0xc5!
ksh93
ведет себя так же, bash
за исключением того, что он обрабатывает как особые случаи, концы которых начинаются с строчных или заглавных букв. В этом случае он сопоставляется только с элементами упорядочения, которые сортируются между этими концами, но которые (или их первый символ для многосимвольных элементов упорядочения) также являются строчными (или прописными соответственно). Так [A-Z]
было бы соответствовать на É
, но не e
так e
же рода между A
и , Z
но не в верхнем регистре , как A
и Z
.
Для fnmatch()
шаблонов (как в find -name '[A-Z]'
) или системных регулярных выражений (как в grep '[A-Z]'
) это зависит от системы и локали. Например, в системе GNU здесь [A-Z]
не совпадает x
в en_GB.UTF-8
локали, но в th_TH.UTF-8
одной. Мне неясно, какую информацию он использует для определения этого, но, очевидно, он основан на справочной таблице, полученной из данных локали LC_COLLATE ).
POSIX разрешает все варианты поведения, поскольку POSIX оставляет поведение диапазонов, не заданных в локалях, отличных от локали C. Теперь мы можем спорить о преимуществах каждого подхода.
bash
Этот подход имеет большой смысл, так как [C-G]
мы хотим, чтобы символы между ними C
и G
. И использование порядка сортировки пользователя для определения того, что находится между ними, является наиболее логичным подходом.
Теперь проблема в том, что это разрушает ожидания многих людей, особенно тех, кто привык к традиционному поведению до Юникода, даже до интернационализации. В то время как от обычного пользователя, это , возможно , ощущение того, что [C-I]
включает в себя h
как h
буква между C
и I
и что [A-g]
не включает в себя Z
, это другое дело для людей , имеющих дело с ASCII только в течение десятилетий.
Это bash
поведение также отличается от [A-Z]
сопоставления диапазонов в других инструментах GNU, таких как регулярные выражения GNU (как в grep
/ sed
...) или fnmatch()
как в find -name
.
Это также означает, что то, что [A-Z]
совпадает, зависит от среды, от ОС и от версии ОС. Тот факт, что [A-Z]
соответствует А, но не Ź, также неоптимален.
Для zsh
/ yash
мы используем другой порядок сортировки. Вместо того, чтобы полагаться на представление пользователя о порядке символов, мы используем значения кода символа. Преимущество этого заключается в том, что его легко понять, но с практической точки зрения немногие за пределами ASCII не очень полезны. [A-Z]
соответствует 26 заглавным буквам английского языка США, [0-9]
соответствует десятичным цифрам. В Unicode есть кодовые точки, которые следуют порядку некоторых алфавитов, но они не обобщены и не могут быть обобщены, так как в любом случае разные люди, использующие один и тот же сценарий, не обязательно соглашаются с порядком букв.
Для традиционных оболочек и mksh, dash, он не работает (теперь, когда большинство людей используют многобайтовые символы), но прежде всего потому, что у них пока нет многобайтовой поддержки. Добавление многобайтовой поддержки для таких оболочек, как bash
и zsh
было огромным усилием, все еще продолжается. yash
(японская оболочка) изначально была разработана с многобайтовой поддержкой с самого начала.
Подход ksh93 имеет то преимущество, что он согласуется с регулярными выражениями системы или fnmatch () (или, по крайней мере, кажется, по крайней мере, в системах GNU). Там это не нарушает ожидание некоторых людей, поскольку [A-Z]
не включает строчные буквы, [A-Z]
включает É
(и Á, но не Ź). Это не соответствует sort
или вообще strcoll()
порядок.
locale
выводит? Я не могу воспроизвести это (touch foo; echo [A-Z]*
выводит буквальный шаблон, а не "foo", в другом пустом каталоге).