LC_COLLATE로 정렬 순서를 지정하여 소문자가 대문자보다 앞에 오도록하십시오


16

주어진 파일 :

$ cat file
1
a
C
B
2
c
3
A
b

기본적으로 sort의지 :

$ sort file
1
2
3
a
A
b
B
c
C

함께 LC_COLLATE=C그래서 소문자 전에 대문자로 정렬합니다 :

$ LC_COLLATE=C sort file
1
2
3
A
B
C
a
b
c

대소 문자 순서, 즉 숫자, 소문자, 대문자를 반대로 정렬 할 수 있습니까?

답변:


8

기본적으로 그 순서대로 정렬되는 로케일을 모르겠습니다. 해결책은 사용자 정의 된 정렬 순서로 사용자 정의 로케일을 작성하는 것입니다. 4 년 후 누군가가 커스텀 방식으로 정렬하고 싶다면 여기 속임수가 있습니다.

대부분의 로케일은 자체 정렬 순서를 지정하지 않고 정의 된 정렬 순서를 복사하여 /usr/share/i18n/locales/iso14651_t1_common편집하려는 것입니다. 원본을 수정하여 거의 모든 로캘의 정렬 순서를 변경하는 대신 iso14651_t1_common복사본을 만드는 것이 좋습니다. 정렬 순서의 작동 방식과 $HOME루트 액세스 권한없이 디렉토리에 사용자 정의 로캘을 만드는 방법에 대한 자세한 내용 은이 질문에 대한 비슷한 질문에 대한 답변에서 찾을 수 있습니다 .

다음 의 항목을 기반으로 방법 aA순서를 살펴보십시오 iso14651_t1_common.

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

b그리고 B비슷합니다 :

<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B

우리는 첫 번째 패스 것을 볼, 모두 aA조합시 기호가 <a>모두 동안, b그리고 B조합시 기호가 <b>. 이후 <a>나타나기 전에 <b>에서 iso14651_t1_common, a그리고 A이전에 연결되어 bB. 두 번째 패스는 네 문자 모두에 조합 기호가 있기 때문에 관계를 끊지 <BAS>않지만 세 번째 패스 중에는 <MIN>대문자에 대한 조합 기호 <CAP>(3488) 전에 소문자에 대한 조합 기호 가 3467 행에 나타나서 관계가 해결 됩니다. . 정렬 순서로 끝나는 그래서 a, A, b, B.

첫 번째와 세 번째 조합 기호를 서로 바꾸면 먼저 대소 문자를 구분하고 (낮은 문자와 대문자를 차례로) 악센트 (악센트가 <BAS>없는 것을 의미), 알파벳 순서로 정렬합니다. 그러나 숫자 <MIN><CAP>숫자가 모두 앞에 오므로 문자 뒤에 숫자를 넣는 원하지 않는 효과가 있습니다.

하면서 먼저 자리를 유지하는 가장 쉬운 방법은 모든 소문자 문자가 앞에 오는 모든 대문자는 모든 동일하게 설정하여 최초의 비교시에 묶어 모든 문자를 강제하는 것입니다 <a>. 대소 문자 내에서 사전 순으로 정렬하려면 마지막 조합 기호를 IGNORE현재 첫 번째 조합 기호로 변경하십시오. 이 패턴을 따르면 다음과 같이됩니다 a.

<U0061> <a>;<BAS>;<MIN>;<a> # 198 a

A 될 것입니다 :

<U0041> <a>;<BAS>;<CAP>;<a> # 517 A

b 될 것입니다 :

<U0062> <a>;<BAS>;<MIN>;<b> # 233 b

B 될 것입니다 :

<U0042> <a>;<BAS>;<CAP>;<b> # 550 B

나머지 글자들도 마찬가지입니다.

의 사용자 정의 버전을 만든 후에는 위에 링크 된 답변iso14651_t1_common 의 지침에 따라 사용자 정의 로캘을 컴파일하십시오.


6

LC_COLLATE=C소문자 전에 대문자를 정렬하기위한 설정 만으로는 충분하지 않습니다. 을 설정해야 할 수도 있습니다 LC_ALL=C.

영숫자가 아닌 문자와 인쇄 할 수없는 문자도 고려하지만, 원하지 않는 경우 옵션을 설정 -d하고 -i(에서 설명 man sort) 해당 기능을 끌 수 있습니다.

ASCII가 아닌 문자를 사용하는 UTF-8과 같이 멀티 바이트 입력에서는 잘못 실패 할 수 있습니다.

대문자 (순서)보다 소문자 (순서대로)를 얻으려면 내가 생각할 수있는 가장 좋은 방법은 본격적인 프로그래밍 언어를 위반하지 않는 가장 좋은 방법은 정렬하기 전에 모든 문자의 대소 문자를 뒤집어 뒤집는 것입니다. 나중에.

tr 'a-zA-Z' 'A-Za-z' < file | LC_ALL=C sort | tr 'a-zA-Z' 'A-Za-z'

2

나는 전문가가 아니지만 데이터 정렬을 정의하는 로케일을 본 적이 없습니다. AFAIK이 데이터 정렬은 ASCII 값을 기반으로하는 C에만 있습니다 . (일반적으로 나는 이것을 스크립트로 해결할 것입니다.)

그러나 나는 이것을 한 적이 없지만 localedef (1)locale (5) 맨 페이지를보고 로케일이 어떻게 정의되고 궁극적으로 자신의 것을 정의하는지 알고 싶을 것입니다.

분음 부호 나 특수 문자가 있으면 C 로케일이 원하는대로 처리하지 않는다는 것을 잊지 마십시오. 예를 들어, á가까이 a또는 Ł가까이에 두지 않습니다 L. 이 경우 언어의 기본 로케일이 더 나은 시작점이 될 것입니다.


0

LC_COLLATE를 변경할 필요가 없다고 생각합니다 (기능을 기본 동작으로 두는 것을 의미합니다).

-f 파일을 정렬

이것은 Linux에서 작동합니다. 유닉스에 있고 다른 버전을 사용하는 경우 명령에 대한 도움말 섹션을 참조하십시오. -f는 무시하는 경우로 정의됩니다.

잘못 배치 된 문법 인 Stephen Rauch에 대한 다소 빠른 수정 및 수정에 감사드립니다.


-1
LC_COLLATE="en_US.UTF-8" sort file

대문자 전에 소문자를 정렬하지 않습니까? ideone.com/Gtyg4Z
iiSeymour

흠, 내 경우에는 귀하의 예를 사용했습니다.
unxnut

4
@unxnut 이것은 올바르지 않습니다. 세미콜론이 없으면이 명령은 환경을 설정 sort하지만 세미콜론을 사용하면 변수가 셸에 국한되며의 동작에 영향을 미치지 않습니다 sort. 변수도 내 보내면 세미콜론을 그대로 유지할 수 있지만 다른 명령에도 영향을 미칩니다.
Anders Sjöqvist
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.