[A-Z]
in 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
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]
).
쉘마다 약간의 차이가 있습니다.
를 들어 zsh
, bash -O globasciiranges
(이상하게라는 이름의 bash-4.3에 도입 된 옵션) schily-sh
및 yash
, [A-Z]
코드 지점 사이에있는 문자에 일치하는지의 A
와의 것을 Z
, 그래서의 동작에 해당 될 bash
C 로케일한다.
재, mksh 및 고대 쉘의 경우 zsh
위와 동일 하지만 1 바이트 문자 세트로 제한됩니다. 즉, 예를 들어 UTF-8 로케일에서는 [É-Ź]
on과 일치하지 Ó
않지만 그 이후로는 [<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]
일치하지 않지만 로케일에서는 일치하지 않습니다 . 그것을 결정하기 위해 어떤 정보를 사용하는지는 확실하지 않지만 LC_COLLATE 로케일 데이터에서 파생 된 조회 테이블을 기반으로합니다 .x
en_GB.UTF-8
th_TH.UTF-8
POSIX는 C 로케일 이외의 로케일에서 범위의 동작을 지정하지 않으므로 POSIX는 모든 동작을 허용합니다. 이제 우리는 각 접근법의 이점에 대해 논쟁 할 수 있습니다.
bash
의 접근 방식은와 마찬가지로 많은 의미를 갖습니다 . 그리고 [C-G]
사이에있는 문자를 원합니다 . 그리고 그 사이 의 내용을 결정하는 데 사용자의 정렬 순서를 사용하는 것이 가장 논리적 인 접근 방법입니다.C
G
이제 문제는 많은 사람들, 특히 유니 코드 이전의 국제 행동, 심지어 국제화 이전의 전통적인 행동에 익숙한 사람들의 기대를 깨뜨리는 것입니다. 일반 사용자에서, 그것은 5 월 의미 기울이고 있으나, [C-I]
포함 h
은 AS h
문자 사이 C
와 I
그는 [A-g]
포함하지 않습니다 Z
, 그것은 사람 만 수십 년 동안 ASCII 처리하는 데에 다른 문제이다.
그 bash
동작은에서 또 다른 [A-Z]
(같이 GNU 정규 표현식에서 같은 다른 GNU 도구의 범위 일치 grep
/ sed
...) 나 fnmatch()
처럼 find -name
.
또한 [A-Z]
일치하는 항목은 환경, OS 및 OS 버전에 따라 다릅니다. [A-Z]
Á와 일치하지만 Ź와 일치하지 않는 사실 도 차선책입니다.
위해 zsh
/ yash
우리는 다른 정렬 순서를 사용합니다. 사용자의 문자 순서 개념에 의존하는 대신 문자 포인트 코드 값을 사용합니다. 그것은 이해하기 쉽다는 이점이 있지만, ASCII 이외의 실용적인 점에서는 그리 유용하지 않습니다. [A-Z]
26 개의 미국 영어 대문자 [0-9]
와 일치하며 10 진수와 일치합니다. 유니 코드에는 일부 알파벳 순서를 따르는 코드 포인트가 있지만 일반화되지 않으며 어쨌든 동일한 스크립트를 사용하는 다른 사람들이 반드시 문자 순서에 동의하지 않기 때문에 일반화 할 수 없습니다.
전통적인 쉘과 mksh, 대시의 경우, 대부분의 사람들이 멀티 바이트 문자를 사용한다는 점에서 깨졌지만 주로 멀티 바이트를 지원하지 않기 때문입니다. 같은 껍질에 멀티 바이트 지원을 추가 bash
하고 zsh
엄청난 노력을하고 아직도 계속되고있다. yash
(일본어 쉘)은 처음부터 멀티 바이트를 지원하도록 설계되었습니다.
ksh93의 접근 방식은 시스템의 정규 표현식 또는 fnmatch ()와 일치하는 이점이 있습니다 (적어도 GNU 시스템에서는 적어도 나타납니다). [A-Z]
소문자를 포함하지 않고 (및 Á [A-Z]
는 포함 É
하지만 Ź 는 포함하지 않음) 일부 사람들의 기대를 깨뜨리지 않습니다. 일치하지 sort
않거나 일반적으로 strcoll()
순서가 다릅니다.
locale
출력 은 무엇입니까 ? 나는 이것을 재현 할 수 없다 (touch foo; echo [A-Z]*
그렇지 않으면 빈 디렉토리에 "foo"가 아닌 리터럴 패턴을 출력한다).