sed가 grep(및 sed 및 awk)에 대한 로케일 대조 파일에 정의된 작업을 수행하지 않는 이유는 무엇입니까?

sed가 grep(및 sed 및 awk)에 대한 로케일 대조 파일에 정의된 작업을 수행하지 않는 이유는 무엇입니까?

모든 (인쇄 ​​가능한) ASCII 문자를 포함하는 파일이 있습니다.

$ printf '%b' "$(printf '\\U%x\n' {32..126})" > file

정렬할 수 있습니다(긴 출력을 한 줄로 줄이려면 tr을 사용하십시오).

$ sort file | tr -d '\n'
 !"#%&'()*+,-./:;<=>?@[\]^_`{|}~$0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ

en_US.utf8 로케일을 사용하는 Debian 버스터 시스템에 표시되는 대조 순서(개별 문자의 경우)는 먼저 구두점, 숫자, 대소문자 혼합 순서입니다. 즉, aAbB, 소문자 및 대문자가 함께 사용됩니다.

이것이 정확하고 사용자(나)가 정리를 원하는 경우라고 가정해 보겠습니다.

그러나 동일한 시스템에서는 다른 변경 사항 없이 다음과 같은 일이 발생합니다.

$ grep '[a-z]' file | tr -d '\n'
abcdefghijklmnopqrstuvwxyz

즉, 범위는 a-z어떤 것에 의해 소문자 ASCII 문자로 변환됩니다.

번역은 누가 수행하며 어떻게 제어하거나 변경할 수 있습니까?

나는 소문자가 무엇인지, [az]가 무엇을 의미하는지, 또는 누군가가 그것이 무엇을 의미하기를 원하는지 묻지 않습니다.

[a-z]이 범위 는 에 시작하고 에 끝나는 범위일 것으로 예상됩니다.az 정렬순서대로.

[a-z]일부 다른 사용자는 모든 로케일에서 의미가 "소문자"와 동일하기를 원한다는 것을 알고 있습니다 . 나는 아마도 기본적으로 "이것과 함께 생활"할 것입니다.

하지만 필요한 경우 이를 어떻게 제어 및/또는 변경할 수 있습니까? 바꿀 수 있는 손잡이가 어디에 있나요?

아니요, 데이터 정렬 파일을 변경해도 도움이 되지 않습니다. 그 이상의 것이 있으며 [a-z]모든 로케일에서 항상 ASCII 소문자를 의미해야 한다는 개인적인 의견을 강요합니다.

답변1

내가 읽은 것POSIX 상태. 내 설명은 두 가지 불평등한 개념이 있다는 것입니다.

  • 정렬 순서(조합 순서)
  • 순서 정렬

관련 스니펫 [강조 내용]:

LC_COLLATE카테고리는 다음을 제공합니다.순서 정렬ls수많은 유틸리티( , 등)의 정의, POSIX.1-2017의 셸 및 유틸리티 볼륨에 있는 sort정규식 일치(정규식 참조) , POSIX.1-2017 의 시스템 인터페이스 볼륨에 있는 strcoll(), strxfrm()wcscoll()함수 .wcsxfrm()

순서 정렬정의에서는 로캘의 데이터 정렬 요소(문자 및 다중 문자 데이터 정렬 요소) 간의 상대적 순서를 정의해야 합니다. 순서는 데이터 정렬 값으로 표현됩니다. 즉, 각 요소에 하나 이상의 데이터 정렬 값(데이터 정렬 가중치라고도 함)을 할당하는 방식입니다. […]

키워드는 order_start다음과 같아야 합니다.순서 정렬항목을 지정하고 해당 항목에 대한 가중치 수를 정의합니다.순서 정렬정의 및 기타 정렬 규칙.

이것순서 정렬이 섹션의 정의는 정규식의 대괄호 표현식 해석에 영향을 미칩니다(RE 대괄호 표현식 참조).

정렬 순서 sort, 즉 가중치가 중요합니다. 데이터 정렬 시퀀스 의 경우 grep '[a-z]'이는 데이터 정렬 시퀀스 항목의 순서입니다.

불행히도 정렬 순서는 다음과 같습니다.명확하게 정의됨이므로 정렬 순서가 다른 개념이라는 명시적인 표시는 없습니다.

정렬 순서
정렬된 요소의 상대적 순서는 LC_COLLATE현재 로캘의 범주 설정에 따라 결정됩니다. 조정 순서는 정렬에 사용되며 각 조정 요소에 할당된 조정 가중치에 따라 결정됩니다. 가중치가 없으면 정렬 순서는 order_start카테고리 내 키워드 간의 정렬 요소 순서를 지정합니다.order_endLC_COLLATE


내 Debian 9에서는 LC_COLLATE많은 로캘 iso14651_t1_common/usr/share/i18n/locales/iso14651_t1_common. 파일의 관련 조각은 다음과 같습니다.

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U00AA> <a>;<PCL>;<EMI>;IGNORE # 199 ª
<U00E1> <a>;<ACA>;<MIN>;IGNORE # 200 á
[…]
<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0253> <b>;<CRL>;<MIN>;IGNORE # 234 ɓ
<U1E03> <b>;<PCT>;<MIN>;IGNORE # 235 ḃ
[…]
<U007A> <z>;<BAS>;<MIN>;IGNORE # 507 z
<U017A> <z>;<ACA>;<MIN>;IGNORE # 508 <z'>
<U017E> <z>;<CAR>;<MIN>;IGNORE # 509 <z<>
[…]
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A
<U00C1> <a>;<ACA>;<CAP>;IGNORE # 518 Á
<U00C0> <a>;<GRA>;<CAP>;IGNORE # 519 À
[…]
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B
<U1E02> <b>;<PCT>;<CAP>;IGNORE # 551 <B.>
<U1E04> <b>;<BPT>;<CAP>;IGNORE # 552 Ḅ
[…]
<U005A> <z>;<BAS>;<CAP>;IGNORE # 813 Z
<U0179> <z>;<ACA>;<CAP>;IGNORE # 814 <Z'>
<U017D> <z>;<CAR>;<CAP>;IGNORE # 815 <Z<>

이것은순서 정렬. ( ) 항목이 및 항목 사이에 없기 [a-z]때문에 포함되지 않습니다 .AA<U0041>az

a항목은 여전히 A​​동일한 데이터 정렬 기호를 지정합니다 <a>. 마찬가지로 지정됩니다 b. 이는 가중치로 변환됩니다.B<b>

<collating-symbol>가중치는 문자(로케일 정의에 지정된 모든 형식), s, <collating-element>s, 타원 또는 특수 기호 로 표현되어야 합니다 IGNORE. 단일 문자 a <collating-symbol>또는 a는 <collating-element>문자 내의 상대적 위치를 나타내야 합니다.순서 정렬문자나 문자 자체가 아닌 문자나 기호입니다. 따라서 가중치에 절대값을 부여하는 대신, 문자 순서를 기준으로 대조 요소에 부여한 상대 순서 값을 이용하여 특정 가중치를 표현한다.순서 정렬.

파일에서 <a>및 는 <b>다음 순서로 정의됩니다.

collating-symbol <a>
collating-symbol <b>

이는 관련 하위 시퀀스를 만듭니다.순서 정렬aAbB. 그게 중요해요 sort.


이를 확인하기 위해 다음 대조 순서 항목을 (임시로) 이동했습니다.

<U004B> <k>;<BAS>;<CAP>;IGNORE # 649 K

에 항목이 들어가기 전의 위치 v, 즉 a와 사이 어딘가 입니다 z. 을 사용하여 로케일을 다시 작성했습니다 locale-gen. 이제 sort file | tr -d '\n'여전히 반환되지만 …iIjJkKlLmM…(가중치는 변경되지 않고 순서는 변경되지 않음) 다음을 grep '[a-z]' file | tr -d '\n'생성합니다.

Kabcdefghijklmnopqrstuvwxyz

이는 K정렬 순서를 변경하여 소속을 만들었다는 의미입니다.[a-z]

대신 grep '[a-z]' file | tr -d '\n'정렬을 반환 하려면 정렬 순서가 다른 로케일을 사용해야 합니다. 사용자 정의 로캘일 수 있습니다.aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZabcdefghijklmnopqrstuvwxyz

관련 정보