[A-Z]
у bash
збігах усіх збірних елементів (символи, але виклик також є послідовністю символів, як 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
У мові С порядок був би таким:
$ 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]
).
Зауважте, що між оболонками є певна різниця.
Для zsh
, bash -O globasciiranges
(дивно з ім'ям опції , введеної в Баш-4.3), schily-sh
і yash
, [A-Z]
матчі на персонажів , чий код точка знаходиться між з A
і в Z
, так було б еквівалентно поведінки bash
в C локалі.
Для золи, мкш та стародавніх мушлі, як і zsh
вище, але обмежено однобайтовими знаками. Тобто у локалі UTF-8, наприклад, [É-Ź]
не збігатиметься Ó
, але оскільки це [<c3><89>-<c5><b9>]
відповідатиме значенням байтів 0x89 до 0xc5!
ksh93
поводиться як bash
виняток, за винятком того, що він розглядає як діапазони спеціальних випадків, кінці яких обидва починаються з малих літер або великих літер. У такому випадку він відповідає лише елементам, що складаються, які сортуються між цими кінцями, але вони (або їх перший символ для елементів, що складаються з кількох символів) також малі (або великі регістри відповідно). Так [A-Z]
було б відповідати на É
, але не e
так e
же роду між A
і , Z
але не в верхньому регістрі , як A
і Z
.
Для fnmatch()
шаблонів (як in find -name '[A-Z]'
) або системних регулярних виразів (як in grep '[A-Z]'
) це залежить від системи та локальної локальності. Наприклад, в системі GNU тут, [A-Z]
не збігається з x
в en_GB.UTF-8
локалі, але це відбувається в th_TH.UTF-8
одному. Мені незрозуміло, яку інформацію він використовує для визначення цього, але , мабуть, він заснований на таблиці пошуку, отриманій з даних локальних даних LC_COLLATE ).
Усі способи поведінки дозволені POSIX, оскільки POSIX залишає поведінку діапазонів не визначеними в інших регіонах, ніж локалі С. Тепер ми можемо сперечатися щодо переваг кожного підходу.
bash
Підхід «S робить багато сенсу , як і [C-G]
, ми хочемо , щоб символи між C
і G
. І використання порядку сортування користувача для того, що визначає, що є між ними, є найбільш логічним підходом.
Тепер проблема полягає в тому, що вона руйнує очікування багатьох людей, особливо тих, хто звик до традиційної поведінки до Unicode, навіть до доінтернаціоналізації. Хоча від звичайного користувача це може мати сенс, що в тому [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, тире, він порушений (зараз більшість людей використовує багатобайтові символи), але насамперед через те, що вони ще не мають багатобайтової підтримки. Додавання багатобайтової підтримки оболонкам, як, bash
і zsh
було величезним зусиллям і триває досі. yash
(японська оболонка) спочатку розроблявся з багатобайтовою підтримкою з самого початку.
Підхід ksh93 має вигоду узгоджуватися з регулярними виразами системи або fnmatch () (або, принаймні, видається принаймні в системах GNU). Там це не порушує сподівання деяких людей, оскільки [A-Z]
не включає малі літери, [A-Z]
включає É
(і Á, але не Ź). Це не відповідає sort
або загалом strcoll()
.
locale
вихід? Я не можу відтворити це (touch foo; echo [A-Z]*
виводить буквальний шаблон, а не "foo", в іншому випадку порожній каталог).