어떤 경우에는 각 개별 문자의 조합 순서를 알아야(사용해야) 합니다. 일반적으로 다음과 같이 표현됩니다.캐릭터 클래스정규 표현식과 같습니다 [b-d]
. 이 문자 클래스는 다음과만 일치합니다.캐릭터주어진 범위 내에서.
어느개인의b-d
문자는 범위(또는 다른 범위) 내의 문자 입니다 .
또한 C 언어 환경의 조합 순서는 각 ASCII 문자의 바이트 값이라는 것을 알아두세요.[ㅏ](33~126 사이의 문자만 표시됩니다):
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
문자 범위가 ASCII 이상으로 확장될 수 있습니까?
하지만:
정렬 순서는 어떻게 되나요?개별 문자다른 지역에서는?
(모든 로케일에서) 이러한 정렬 순서를 표시하는 방법이 있나요?
[ㅏ]ASCII를 사용하는 시스템(대부분의 시스템)에서는 다른 시스템에서는 EBCDIC 또는 다른 시스템을 사용할 수도 있습니다.
답변1
여기에는 몇 가지 측면이 있습니다. 로케일의 문자 집합에 있는 모든 문자를 나열하고 그래픽 문자(예: 33~126개의 ASCII 문자)를 선택한 다음 정렬해야 합니다.
문자의 정렬 순서에 관해 이야기하는 것이 타당한지, 아니면 정의된 적이 있는지에 대한 질문도 있습니다. 마지막 요점부터 시작하겠습니다.
POSIX 교정 알고리즘
, 또는 , 쉘 글로브 또는 / , 문자열 비교 연산자에 의해 구현되고 사용되는 C/POSIX 정렬 알고리즘과 더 일반적으로 POSIX 시스템에서 사용자의 로케일을 기반으로 텍스트를 정렬하는 대부분의 도구에 대해 이야기하는 경우 strcoll()
비교용이라는 점에 유의하세요.sort
ls
awk
expr
<
>
끈.
GNU 시스템의 en_US.UTF-8 로케일에서는 é
단일 é
문자로 구성된 문자열이 정렬됩니다.뒤쪽에단일 문자로 구성된 문자열 e
, Stéphane
정렬됨앞으로 Stephanie
. cs_CZ.UTF-8 로케일에서는 c
와 사이에서 정렬하지만 사이에서는 정렬하지 않습니다.b
d
ch
h
i
대조 알고리즘은 개별 문자가 아닌 전체 문자열을 고려합니다. 따라서 개별적으로 비교할 때 문자의 순서를 아는 것이 해당 문자를 포함하는 문자열이 어떻게 비교되는지 반드시 알려주는 것은 아닙니다.
이 알고리즘은 많은 실제 언어(사전, 전화번호부 등)와 같은 문자열을 비교하도록 설계되었습니다. 다양한 문화권에서 정렬의 모든 미묘함을 다루기에는 다소 너무 단순합니다.중환자실, 더 다양한 알고리즘을 구현하지만) 대부분의 경우에는 충분합니다.
이 알고리즘에서는요소 구성, 여기에는 문자뿐만 아니라 한국어 알파벳이나 체코어의 다중 부분 문자소와 같은 문자 조합도 포함됩니다. ch
또는 일부 시스템에서는 조합 뒤에 결합된 예음(U+0301)이 여러 개 할당된 형태 é
로 표시됩니다.e
무게.
그리고전체 문자열비교는 초기 가중치부터 마지막 가중치까지 차례로 각 가중치를 사용하여 수행됩니다.
예를 들어, 이 en_US.UTF-8
GNU 로케일에서 , E
, é
는 e
모두 É
동일한 기본 가중치를 갖습니다. Stéphane
그리고 Stephanie
로 분해
<S><t><é><p><h><a><n> <e>
<S><t><e><p><h><a><n> <i><e>
요소 조합(여기서는 문자당 하나).
현재로서는 n
두 문자열의 대조 요소는 동일한 주요 가중치를 가지지만 의 i
주요 가중치는 e
s보다 크므로 Stephanie
정렬 후에는 Stéphane
보조 가중치를 고려할 필요도 없습니다.
이제 Stephane
vs 의 Stéphane
경우 기본 가중치를 비교할 때 동일하게 정렬되므로 보조 가중치를 고려해야 합니다. /usr/share/i18n/locales/iso14651_t1_common
en_US.UTF-8 로케일을 있는 그대로 사용하여 GNU 시스템을 살펴보면 다음을 볼 수 있습니다.
<BAS> # 15
[...]
<ACA> # 18
[...]
<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U00E9> <e>;<ACA>;<MIN>;IGNORE # 260 é
라틴 알파벳 문자의 경우 발음 구별 부호를 비교하기 위해 보조 가중치가 사용됩니다. 기본 문자( BAS
)는 급성 악센트( )가 있는 문자 앞에 옵니다 ACA
. 따라서 Stéphane
순서는 에 있습니다 . 와 비교하려면 Stephane
영어 에서 대문자가 소문자 뒤에 오는 세 번째 가중치에 도달해야 합니다(예를 들어 에스토니아어와 반대).STÉPHANE
Stéphane
IGNORE
또한 첫 번째 비교에서 주요 가중치가 고려되거나 고려되지 않는 공백이나 구두점과 같은 영숫자가 아닌 문자도 있습니다 ( de facto
이 문자는 및 사이에 정렬되지만 공백이 및 사이에 정렬된다는 의미는 아닙니다).deface
degree
f
g
$'STE\u0301HANE'
vs 의 경우 Stéphane
일부 시스템(예: Solaris)은 마지막 문자가 (U+00C9) 문자 E\u0301
라는 점을 제외하고 이를 동일한 가중치를 가진 대조 요소 로 처리하는 반면, 일부 다른 시스템은 이를 구두점으로 처리하여 결과를 제공합니다. 좋습니다( 이전의 것과 같습니다 ).É
\u0301
$'STE\u0301HANE'
Stephane
하나도 아니야모두주문하다
GNU 시스템에서U+0301의 정렬 순서도 정의되어 있지 않으며 이 경우 수천 개의 문자가 있습니다.. 나는 반올림된 숫자(U+2460..U+2473)를 예로 사용하고 싶습니다. 왜냐하면 이 숫자에는 분명히 정렬 순서가 있어야 하지만 그렇지 않기 때문입니다.
$ touch ① ② ③ ④ ⑤
$ ls
④ ③ ⑤ ② ①
$ ls | sort -u
④
실제로 다른 문자와 동일한 가중치를 갖도록 정의된 일부 문자도 있습니다(예 Ǝ
: Ə
, Ɛ
여기에서는 순서가 모두 동일합니다).
sort
따라서 일부 구현에서 수행하는 경우를 제외하고 일부 로케일에서는 임의의 문자를 정렬하는 것이 실제로 불가능합니다.이는 POSIX 사양의 다음 주요 버전의 요구 사항이 될 것입니다.), memcmp()
동일한 순서의 문자에 대해 유사한 비교를 수행할 수 있습니다.
로케일 문자 세트의 모든 그래픽 문자 나열
로케일마다 다른 문자 집합을 사용할 수 있습니다.
문자 세트에는 세 가지 주요 범주가 있습니다. ASCII 또는 iso-8859-x와 같은 단일 바이트 문자 세트(각 바이트는 문자에 해당함)(일부는 정의되지 않을 수 있음), 문자가 서로 다른 바이트 수로 인코딩되는 UTF-8, GB18030, BIG5 또는 EUCJP와 같은 상태 저장 바이트(1바이트 또는 바이트 시퀀스는 변환 코드 전에 상태가 방출되었는지 여부에 따라 다른 문자를 나타낼 수 있음)
마지막 범주는 요즘 로케일에서 거의 사용되지 않고 관리하기 어려운 경우가 많으므로 지금은 무시해도 됩니다.
C 로케일은 본질적으로 단일 바이트 문자 집합을 갖도록 보장됩니다. EBCDIC 기반이 아닌 시스템에서 일반적으로 발견되지만 반드시 ASCII일 필요는 없습니다.
일부 스크립트(예: 영어에 사용되는 라틴 스크립트)는 왼쪽에서 오른쪽으로 작성되고 다른 일부 스크립트는 오른쪽에서 왼쪽으로 작성되므로 이러한 다른 스크립트(일부 문자 세트에서 지원됨)의 문자는 같은 줄에 있습니다. 반드시 좋은 생각은 아닙니다.
캐릭터 조합도 마찬가지인데, 결국 무작위 캐릭터로 조합되어 합쳐지게 됩니다.
또한 유니코드와 같은 일부 문자 집합은 계속해서 발전하고 있습니다. 현재 코드 포인트 범위는 0..0xD7FF, 0xE000..0x10FFFF로 고정되어 있지만 대부분은 여전히 할당되지 않고 있으며 새로운 버전의 유니코드마다 새로운 코드 포인트 범위가 할당되며 시스템 공급업체에서는 이에 맞춰 노력하고 있습니다.
graph
로 분류된 문자는 ISO/IEC TR 14652(2002)의 후속인 ISO/IEC 30112 기술 보고서(2014)에 나열되어 있습니다. GNU 로케일은 이것을 따르는 것처럼 보이지만 일부 다른 로케일(FreeBSD/Solaris와 같은)은 그렇지 않습니다. 그러나 제게는 별 의미가 없는 것 같기 때문에 그들을 비난하지는 않습니다. 예를 들어 대부분의 공백 문자는 제외되지만 U+00A0(단순 공백), U+2007(숫자 공백) 또는 U+200B(너비가 0인 공백)은 제외됩니다. 제 생각엔 캐릭터가 포함되어 있는 것 같아요제어U+200C..U+200F, U+202D, U+202E...²와 같은 문자표지는 오른쪽에서 왼쪽으로이 Q&A에서 중요한 점은 문자 순서가 왼쪽에서 오른쪽으로 바뀌는 것입니다.
$ printf '%b\n' '\u202E' a b c | sort | paste -sd '\0' -
abc
(일부 브라우저에서는 cba
지원 여부가 표시되고 다른 브라우저에서는 지원 여부가 표시됩니다 abc
).
또한 대부분의 내용이 포함됩니다.상표수치수천 개가 더 있습니다사용시스템에 그릴 수 있는 것은 물론이고 할당될 가능성도 없는 문자입니다.
단일 바이트 문자 세트(GNU 시스템에서는 locale ctype-mb-cur-max
1을 반환하는 문자 세트)의 경우 그래픽 문자 나열은 모든 255바이트 값을 반복해야 합니다(첫 번째를 무시하면 각 문자 세트의 NUL은 그래픽 문자 세트가 아닙니다. 문제가 발생할 수 있음)과 일치시킵니다 [[:graph:]]
.
awk
예를 들어 다음과 같이 할 수 있습니다.
awk '
BEGIN{
for (i = 1; i < 256; i++) {
c = sprintf("%c", i)
if (c ~ /[[:graph:]]/) print c
}
}' | sort | paste -sd '\0' -
iso8859-7 단일 바이트 문자 집합을 사용하는 그리스어 로케일에서는 el_GR.iso88597
다음이 제공됩니다.
`^¨~<=>¦°_-,;:!?/.·'ʽʼ"«»()[]{}§©@$£¤¥*\&#%+±ª―΄΅0½12²3³456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZΑαΆάΒβΓγΔδΕεΈέΖζΗηΉήΘθΙιΊίΪϊΐΚκΛλΜμΝνΞξΟοΌόΠπΡρΣσςΤτΥυΎύΫϋΰΦφΧχΨψΩωΏώ
(뒤에 나오는 잘림 방지 공백은 GNU 로케일에서 "그래픽"으로 잘못 분류됩니다.)
이 방법은 멀티바이트 문자와 함께 사용할 수 없습니다.
또는 문자 집합 인코딩을 iconv
지원하는 경우 모든 유니코드 코드 포인트를 32비트 빅엔디안 숫자로 생성하고 이를 로케일의 문자 집합으로 변환할 수 있습니다.UCS-4BE
UTF32BE
perl -e 'print pack("L>*", $_, 10) for 1..0xd7ff, 0xe000..0x10ffff' |
iconv -cf UCS-4BE |
grep '[[:graph:]]' |
sort
또는 UTF-8을 지원하는 경우:
perl -C -M-warnings=nonchar -le 'print chr$_ for 1..0xd7ff, 0xe000..0x10ffff' |
iconv -cf UTF-8 |
grep '[[:graph:]]' |
sort
(위의 문제를 방지하고 줄이 너무 길어지는 것을 방지하려면 한 줄에 한 문자씩 예약하세요.)
이는 유니코드(및 해당 인코딩)가 다른 모든 가능한 문자 집합의 문자를 포함하도록 설계되었기 때문에 모든 문자 집합의 모든 문자에는 항상 유니코드 코드 포인트가 있습니다. 최신 시스템은 실제로 유니코드 측면에서 문자 집합을 정의하며 wchar_t
일반적으로 유니코드 코드 포인트에 해당합니다.
이제 위에서 언급한 대로 정렬에서는 memcmp()
정렬과 동일한 문자 비교를 기반으로 하는 비교를 사용합니다 strcoll()
. 단일 바이트 문자 집합의 경우 해당 문자 집합 내의 코드 포인트를 기준으로 정렬됩니다. UTF-8의 경우 UTF-8에 특정 속성이 있으므로 유니코드 코드 포인트를 기준으로 정렬됩니다. 다른 유니코드 인코딩(예: 중국어 GB18030 또는 기타 멀티바이트 문자 집합)의 경우 이는 다소 무작위로 나타날 수 있습니다.
그럼에도 불구하고 이는 정렬 순서가 동일한 두 로캘의 경우 sort
해당 로캘이 다른 문자 집합을 사용하면 출력이 달라짐을 의미합니다.
예를 들어, ① ② ③ ④ ⑤ ⑥ ⑦ ─ ⑩⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳ 반올림된 숫자로 돌아가면. 유니코드는 이를 해당 순서(코드 포인트 0x2460 ~ 0x2473)로 지정합니다. GNU 로케일에서는 순서가 정의되지 않습니다(①이 ②보다 앞도 뒤도 안 됨). UTF-8을 사용하는 로케일에서는 UTF-8 순서가 유니코드 코드 포인트 순서를 따르므로 ① 다음에 ②를 정렬합니다. 그러나 GB18030(중국의 또 다른 유니코드 인코딩)을 사용하는 zh_CN.gb18030과 같은 로케일에서는 해당 문자가 바이트 수준에서 인코딩되는 방식에 따라 순서가 ⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳123456789⑩가 됩니다.이 오류이렇게 하면 순서는 ① ② ③ ④ ⑤ ⑥ ⑧ ⑩⑮⑯⑰⑱⑲⑳⑪⑫⑬⑭)입니다.
데이터 정렬에 따라 문자열의 문자를 정렬하려면 다음을 사용하십시오 zsh
.
printf "%s\n" ${(j::)${(s::o)string}}
zsh는 변수에 NUL 문자를 포함할 수 있지만 strcoll()
이러한 문자에서는 작동하지 않습니다. zsh
이 문제를 해결하려고 노력했지만완벽하지 않아.
문자열에 동일한 정렬 순서를 가진 다른 문자가 포함되어 있으면 결과가 정의되지 않습니다.
^2019년 편집새로운 버전의 GNU libc에서는 ① ② ③ ④ ⑤의 순서가 수정되었지만 2.30 현재 95% 이상의 문자가 여전히 정의된 순서가 없습니다.
답변2
Bash와 zsh에서는 일련의 숫자를 생성하는 것이 쉽습니다.
$ printf '\\x%x' {53..63}
\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f
UNICODE 숫자를 문자로 변환하는 것도 쉽습니다.
$ printf '%b' "$(printf '\\U%x' {53..63})"
56789:;<=>?
이것은 bash 코더를 위한 선물이며 \UXXXXXXXX
제한이 없습니다. 코드 0에서 10FFFF(십진수로 1114111)까지 작동합니다.
따라서 다음의 간단한 코드를 사용하여 처음 127자를 모두 생성할 수 있습니다.
$ printf '%b' "$(printf '\\U%x' {0..127})" | hd
00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./|
00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?|
00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO|
00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_|
00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno|
00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.|
00000080
각 문자에 NUL(0x00) 문자를 추가하고 sort -z를 사용하면 정렬 순서를 볼 수 있습니다.
$ printf '%b' "$(printf '\\U%x\\0' {0..127})" | sort -z
`^~<=>| _-,;:!?/.'"()[]{}@$*\&#%+
▒▒123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
그리고 NUL을 제거하여 숫자 순서를 확인하세요.
$ printf '%b' "$(printf '\\U%x\\0' {0..127})" | sort -z | tr -d '\0' | hd
00000000 60 5e 7e 3c 3d 3e 7c 20 5f 2d 2c 3b 3a 21 3f 2f |`^~<=>| _-,;:!?/|
00000010 2e 27 22 28 29 5b 5d 7b 7d 40 24 2a 5c 26 23 25 |.'"()[]{}@$*\&#%|
00000020 2b 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |+...............|
00000030 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
00000040 7f 30 31 32 33 34 35 36 37 38 39 61 41 62 42 63 |.0123456789aAbBc|
00000050 43 64 44 65 45 66 46 67 47 68 48 69 49 6a 4a 6b |CdDeEfFgGhHiIjJk|
00000060 4b 6c 4c 6d 4d 6e 4e 6f 4f 70 50 71 51 72 52 73 |KlLmMnNoOpPqQrRs|
00000070 53 74 54 75 55 76 56 77 57 78 58 79 59 7a 5a |StTuUvVwWxXyYzZ|
0000007f
C 로캘 순서와의 차이점에 유의하세요.
$ printf '%b' "$(printf '\\U%x\\0' {0..127})" | LC_COLLATE=C sort -z | tr -d '\0' | hd
00000000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 |................|
00000010 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
00000020 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
00000030 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 |123456789:;<=>?@|
00000040 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 |ABCDEFGHIJKLMNOP|
00000050 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 |QRSTUVWXYZ[\]^_`|
00000060 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 |abcdefghijklmnop|
00000070 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |qrstuvwxyz{|}~.|
0000007f
바이트는 ASCII 범위 밖의 128개 값을 가질 수 있으며 utf8로 인쇄됩니다. 항복(데이터 정렬로 정렬되지 않음):
$ printf '%b' "$(printf '\\U%x' {125..255})"
}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
조합 순서의 동일한 범위는 다음과 같습니다(첫 번째 문자는 급성 악센트이며 소문자 및 대문자 모음이 교대로 나타남).
$ printf '%b' "$(printf '\\U%x\\0' {125..255})" | sort -z
´¨~÷׬¦°µ¯¡¿·¸«»}§¶©®¤¢£¥±¼½¾¹²³áÁàÀâÂåÅäÄãêæÆ
çÇðÐéÉèÈêÊëËíÍìÌîÎïÏñÑóÓòÒôÔöÖõÕøغßúÚùÙûÛüÜýÝÿþÞ
범위가 확장되면 정렬 순서가 더욱 복잡해집니다.
$ printf '%b' "$(printf '\\U%x\\0' {0..500})" | sort -z | tr -d '\0'
´`^¨~÷×<=>¬|¦°µ _¯-,;:!¡?¿/.·¸'"«»()[]{}§¶©®@¤¢$£¥*\&#%+
±ƀƂƃƄƅƉƋƌƍƑƒƔƖƗƚƛƜƝƞƤƥƦƧƨƩƪƫƬƭƮƱƲƸƹƺƻƼƽƾǀǁǂǃ
▒▒0¼½¾1¹2²3³456789aAáÁàÀăĂâÂǎǍåÅäǟÄǞãÃǡǠąĄāĀªæǣÆǢ
bBƁcCćĆĉĈčČċĊçÇƈƇdDďĎđĐƊðÐdzDzDZdžDžDŽeEéÉèÈĕĔêÊěĚëËėĖęĘēĒǝƎƏƐ
fFgGǴğĞĝĜǧǦġĠǥǤģĢƓƣƢhHĥĤħĦƕiIíÍìÌĭĬîÎǐǏïÏĩĨįĮīĪıİijIJ
jJĵĴǰkKǩǨķĶƙƘlLĺĹľĽŀĿłŁļĻljLjLJmMnNńŃňŇñÑņŅʼnŋŊnjNjNJ
oOóÓòÒŏŎôÔǒǑöÖƟőŐõÕøØǫǭǪǬōŌơƠºƆœŒpPqQĸrRŕŔřŘŗŖ
sSśŚŝŜšŠşŞſßtTťŤŧŦţŢuUúÚùÙŭŬûÛǔǓůŮüǘǜǚǖÜǗǛǙǕűŰũŨųŲūŪưƯ
vVwWŵŴƿxXyYýÝŷŶÿŸƴƳzZźŹžŽżŻƶƵþÞƷǯǮ
printf가 utf8에서 문자를 바이트 쌍으로 생성하고 sort(순수 C 로캘 사용)가 바이트 정렬을 시도하기 때문에 이러한 큰 문자 그룹을 정렬하는 것은 순수 C 로캘에서는 불가능합니다. 그렇지 않으면 \U…
C 로케일에서 printf가 실패합니다 . 필요한 것은 1바이트에 들어갈 수 있는 256자보다 더 많은 문자를 허용하는 동등한 로케일입니다.
$ LC_ALL=C.UTF-8 printf "$(printf '\\U%x' {32..500})" | sort
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·
¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñò
óôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭ
ĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨ
ũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣ
ƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞ
ǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ
답변3
조합 순서는 로케일 파일에 의해 정의됩니다. 다음은 en_US 로케일의 모든 ASCII 문자 시퀀스입니다.
codes=$(for i in {32..126}; do echo "u$(printf '%04x' "$i")"; done)
grep_patterns=$(echo "$codes" | sed 's/^/^</; s/$/>/')
codes_locale=$(grep -oif - <<<"$grep_patterns" /usr/share/i18n/locales/iso14651_t1_common | tr -d '<>')
# "ASCII sequence"
for c in $codes; do echo -ne "\\$c"; done; echo
# "en_US sequence"
for c in $codes_locale; do echo -ne "\\$c"; done; echo
# OUTPUT:
# !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
# !"#%&'()*+,-./:;<=>?@[\]^_`{|}~$0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
순서 순서는 정렬 순서와 동일하지 않다는 점을 기억해야 합니다. 정렬 중에는 추가 규칙이 적용됩니다.