두 개의 필드를 먼저 정렬해 보세요. 먼저 두 번째, 첫 번째 필드를 정렬해 보세요.

두 개의 필드를 먼저 정렬해 보세요. 먼저 두 번째, 첫 번째 필드를 정렬해 보세요.

여러 열을 정렬하려고 합니다. 결과는 예상과 달랐습니다.

이것은 내 데이터입니다(people.txt).

Simon Strange 62
Pete Brown 37
Mark Brown 46
Stefan Heinz 52
Tony Bedford 50
John Strange 51
Fred Bloggs 22
James Bedford 21
Emily Bedford 18
Ana Villamor 44
Alice Villamor 50
Francis Chepstow 56

다음은 올바르게 실행됩니다.

bash-3.2$ sort -k2 -k3 <people.txt                                                                                                                    
Emily Bedford 18                                                                                                                                      
James Bedford 21                                                                                                                                      
Tony Bedford 50                                                                                                                                       
Fred Bloggs 22                                                                                                                                        
Pete Brown 37                                                                                                                                         
Mark Brown 46                                                                                                                                         
Francis Chepstow 56                                                                                                                                   
Stefan Heinz 52                                                                                                                                       
John Strange 51                                                                                                                                       
Simon Strange 62                                                                                                                                      
Ana Villamor 44                                                                                                                                       
Alice Villamor 50

그러나 다음은 예상대로 작동하지 않습니다.

bash-3.2$ sort -k2 -k1 <people.txt                                        
Emily Bedford 18                                                                                                                                      
James Bedford 21                                                                                                                                      
Tony Bedford 50                                                                                                                                       
Fred Bloggs 22                                                                                                                                        
Pete Brown 37                                                                                                                                         
Mark Brown 46                                                                                                                                         
Francis Chepstow 56                                                                                                                                   
Stefan Heinz 52                                                                                                                                       
John Strange 51                                                                                                                                       
Simon Strange 62                                                                                                                                      
Ana Villamor 44                                                                                                                                       
Alice Villamor 50

성, 이름 순으로 정렬해 보았지만 Veramos의 순서가 올바르지 않은 것을 알 수 있습니다. 성으로 정렬한 다음 성이 일치하면 이름으로 정렬하고 싶습니다.

나는 이것이 어떻게 작동하는지 이해할 수 없는 것 같습니다. 물론 다른 방법(awk를 사용하여)을 수행할 수도 있지만 정렬을 이해하고 싶습니다.

저는 Mac OS X에서 표준 Bash 쉘을 사용하고 있습니다.

답변1

키와 같은 지정은 -k22부터 줄 끝까지의 모든 필드가 고려된다는 의미입니다. 그래서 Villamor 44그것은 전에 끝났습니다 Villamor 50. 두 행이 동일하지 않으므로 첫 번째 비교 sort -k2 -k1만으로 두 행을 구별하기에 충분하며 -k1두 번째 정렬 키는 호출되지 않습니다. 두 명의 Villamo가 같은 나이인 경우 -k1이름을 기준으로 정렬됩니다.

단일 열을 기준으로 정렬하려면 -k2,2키 사양으로 사용하세요. 이는 #2에서 #2까지의 필드, 즉 두 번째 필드만 사용함을 의미합니다.

sort -k2 -k3 <people.txt중복됨: sort -k2 <people.txt성, 이름, 나이를 기준으로 정렬하려면 다음 명령을 실행하세요.

sort -k2,2 -k1,1 <people.txt

또는 동등하게, sort -k2,2 -k1 <people.txt이 세 개의 필드만 있고 구분 기호가 동일하기 때문입니다. 실제로 행 하위 집합의 모든 키가 동일한 경우 최후의 수단으로 전체 행을 사용하는 sort -k2,2 <people.txt것과 동일한 효과를 얻을 수 있습니다.sort

또한 기본 필드 구분 기호는 공백이 아닌 공백과 공백 사이의 전환이므로 키에 선행 공백이 포함됩니다. 예를 들어 첫 번째 행의 경우 첫 번째 키는 이지만 "Emily"두 번째 키 " Bedford"는 입니다. 추가 -b제거 빈 옵션:

sort -b -k2,2 -k1,1

b키 실행 사양 끝에 플래그를 추가하여 키별로 이 작업을 수행할 수도 있습니다.

sort -k2b,2 -k1,1 <people.txt

그러나 한 가지 기억해야 할 점은 이러한 플래그를 키 사양에 추가하면 전역 플래그(예: -n, -r...)가 더 이상 해당 플래그에 적용되지 않으므로 키별 플래그와 전역 플래그를 혼합하지 않는 것이 가장 좋습니다.

답변2

GNU의 경우 sort이렇게 할 수 있지만 MacOS의 경우 확실하지 않습니다.

sort -k2,2 -k1 <people.txt

고쳐 쓰다댓글을 기준으로 합니다. 인용 출처 man sort:

   -k, --key=KEYDEF
          sort via a key; KEYDEF gives location and type

   KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where
   F is a field number and C a character position in the field; both are
   origin 1, and the stop position defaults to the line's end.

답변3

당신은 이것을 할 수 있습니다

$ sort -k2,2 -k1,1 people.txt 
Emily Bedford 18
James Bedford 21
Tony Bedford 50
Fred Bloggs 22
Mark Brown 46
Pete Brown 37
Francis Chepstow 56
Stefan Heinz 52
John Strange 51
Simon Strange 62
Alice Villamor 50
Ana Villamor 44

먼저 -k2,2성으로 정렬하고 싶습니다. 그런 다음 k1,1이름별로 정렬합니다.

답변4

사용행복하다(이전 Perl_6)

유니코드를 정렬하려는 U&L 사용자를 위해 이 답변을 추가합니다. Raku에는 내장된 유니코드에 대한 고급 지원이 있으며 이 답변은 (부분적으로) 작성자가 Raku의 데이터 정렬을 이해하는 데 도움을 주기 위한 것입니다.


"단항" 비교 연산자/블록(상단에 주석 처리됨) 또는 다음을 포함하는 이진 블록을 사용하여 하나의 열(성)을 기준으로 정렬합니다.leg "보다 작다/같다/보다 크다" 비교 연산자. 동점은 "만남" 순서를 유지합니다(예:안정적인 정렬):

~$ #`{ raku -e '.put for lines.sort: { .words[1] };'  #unary block, OR binary block below: }

~$ raku -e '.put for lines.sort: { $^a.words[1] leg $^b.words[1] };'  file
Tony Bedford 50
James Bedford 21
Emily Bedford 18
Fred Bloggs 22
Pete Brown 37
Mark Brown 46
Francis Chepstow 56
Stefan Heinz 52
Simon Strange 62
John Strange 51
Ana Villamor 44
Alice Villamor 50

두 개의 열을 기준으로 정렬합니다(이름, 성, 이름). 상단(주석 처리)에 sort정렬할 요소의 단항 목록을 제공합니다. 아래의 두 번째 예: 사이에 "단락 OR"을 사용하여 두 개의 leg문자열 비교 연산자를 보다 명시적으로 사용합니다.||

~$ #`{ raku -e '.put for lines.sort: { .words.[1], .words.[0] }; #list of unary elements, OR binary blocks below: }

~$ raku -e '.put for lines.sort: {$^a.words[1] leg $^b.words[1] || $^a.words[0] leg $^b.words[0] };'  file
Emily Bedford 18
James Bedford 21
Tony Bedford 50
Fred Bloggs 22
Mark Brown 46
Pete Brown 37
Francis Chepstow 56
Stefan Heinz 52
John Strange 51
Simon Strange 62
Alice Villamor 50
Ana Villamor 44

위의 Raku 코드는 이 질문의 제목을 만족합니다."두 필드를 정렬해 보세요. 두 번째 필드, 첫 번째 필드입니다.". 그러나 열이 숫자인 경우 숫자로 정렬하는 <=>대신 다음을 사용할 수 있습니다.leg<=>'우주선'운영자). 아래 예:


다음은 성, 역연령(가장 오래된 것부터 교체 $^b$^a역정렬에 사용됨), 이름 등 3개 열을 정렬합니다. 따라서 정렬된 출력 Simon Strange 62앞에 표시됩니다 John Strange 51.

Raku에는 cmp유형을 감지하고 스마트 비교를 수행하는 향상된 연산자가 있습니다(예: 문자열 비교 leg및 ​​숫자 비교 비교 <=>). 아래 두 번째 예에서는 cmp비교 결과는 첫 번째 예와 정확히 동일한 정렬된 출력을 제공합니다.

~$ #`{ raku -e '.put for lines.sort: {$^a.words[1] leg $^b.words[1] || $^b.words[2] <=> $^a.words[2] || $^a.words[0] leg $^b.words[0] };' #OR with cmp operator below: }

~$ raku -e '.put for lines.sort: {$^a.words[1] cmp $^b.words[1] || $^b.words[2] cmp $^a.words[2] || $^a.words[0] cmp $^b.words[0] };'  file
Tony Bedford 50
James Bedford 21
Emily Bedford 18
Fred Bloggs 22
Mark Brown 46
Pete Brown 37
Francis Chepstow 56
Stefan Heinz 52
Simon Strange 62
John Strange 51
Alice Villamor 50
Ana Villamor 44

마지막으로 "Binary Comparator Block"(위)을 사용하면 정렬 메커니즘을 정확하게 이해하고 제어할 수 있습니다. 그러나 원하는 경우 위의 세 열을 정렬하는 작업을 다음 코드로 단순화할 수 있습니다.

~$ raku -e '.put for lines.sort: { ~.words[1], -.words[2], ~.words[0] };'  file
Tony Bedford 50
James Bedford 21
Emily Bedford 18
Fred Bloggs 22
Mark Brown 46
Pete Brown 37
Francis Chepstow 56
Stefan Heinz 52
Simon Strange 62
John Strange 51
Alice Villamor 50
Ana Villamor 44

https://perl6advent.wordpress.com/2013/12/23/day-23-unary-sort/ https://docs.raku.org/언어/101-basics#Stable_sort
https://docs.raku.org/routine/sort
https://docs.raku.org/routine/cmp
https://perl6advent.wordpress.com/2013/12/23/day-23-unary-sort/
https://raku.org

관련 정보