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 로케일을 사용하는 데비안 버스터 컴퓨터에서 한 부씩 정렬(단일 문자에 대한)은 먼저 모든 구두점을 갖고 그 다음에는 숫자, 그 다음은 대소문자 혼합을 포함함을 보여줍니다. 즉, 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대조 순서POSIX.1-2017의 셸 및 유틸리티 볼륨에 있는 다양한 유틸리티( , 등)에 대한 정의 ls, sort정규식 일치(정규식 참조), POSIX.1- 시스템 인터페이스 볼륨의 strcoll(), strxfrm(), wcscoll()및 함수에 대한 정의 wcsxfrm()2017.

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

키워드 order_start가 앞에 있어야 합니다.대조 순서항목을 정의하고 이에 대한 가중치 수를 정의합니다.대조 순서정의 및 기타 대조 규칙.

그만큼대조 순서이 섹션에 정의된 대로 정규식의 대괄호 표현식 해석에 영향을 미칩니다(RE 대괄호 표현식 참조).

sort대조 순서 의 경우 가중치, 즉 가중치가 중요합니다. 대조 순서 문제 의 경우 grep '[a-z]', 즉 대조 순서 항목의 순서입니다.

불행하게도 데이터 정렬 순서만명시적으로 정의됨, 따라서 대조 순서가 다른 개념이라는 명확한 표시는 없습니다.

조합 순서 현재 로케일의 범주
설정에 따라 결정되는 조합 요소의 상대적 순서입니다 . LC_COLLATE조합 순서는 정렬에 사용되며 각 조합 요소에 할당된 조합 가중치에 따라 결정됩니다. 가중치가 없는 경우 조합 순서는 범주 의 키워드 order_start사이 에 조합 요소가 지정되는 순서입니다 .order_endLC_COLLATE


내 데비안 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>bB<b>

가중치는 문자(로케일 정의에 지정된 형식 중 하나로), <collating-symbol>s, <collating-element>s, 줄임표 또는 특수 기호 로 표현됩니다 IGNORE. 단일 문자 a <collating-symbol>또는 a는 <collating-element>문자의 상대적 위치를 나타냅니다.대조 순서문자나 문자 자체보다는 문자나 기호의 의미입니다. 따라서 가중치에 절대값을 부여하는 것이 아니라 문자 내 순서에 따라 조합 요소에 할당된 상대 순서 값을 사용하여 특정 가중치를 표현합니다.대조 순서.

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

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

이는 관련 하위 시퀀스를 만듭니다.대조 순서BE aAbB. 이것이 중요합니다 sort.


이를 확인하기 위해 (일시적으로) 다음 정렬 순서 항목을 이동했습니다.

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

에 대한 항목 바로 앞 위치 , 즉 와 v사이 어딘가에 위치합니다 . 으로 로케일을 다시 작성했습니다 . 이제 여전히 반환되지만 (가중치는 변경되지 않았으며 대조 순서는 변경되지 않았습니다) 다음을 생성합니다.azlocale-gensort file | tr -d '\n'…iIjJkKlLmM…grep '[a-z]' file | tr -d '\n'

Kabcdefghijklmnopqrstuvwxyz

이는 조합 순서를 변경하여 내가 K속하게 되었음을 의미합니다.[a-z]

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

관련 정보