두 번째 필드를 정렬하려고 시도합니다. 두 번째로 먼저


106

여러 열을 정렬하려고합니다. 결과가 예상과 다릅니다.

내 데이터는 다음과 같습니다 (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

성으로 정렬 한 다음 이름별로 정렬하려고했지만 Villamors가 올바른 순서로 표시되지 않습니다. 나는 성을 기준으로 정렬하고 성이 일치하면 이름을 기준으로 정렬하기를 바랐습니다.

이해가 안되는 방법에 대한 내용이있는 것 같습니다. 나는 이것을 다른 방법으로 할 수 있지만 (awk 사용) 정렬을 이해하고 싶습니다.

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

답변:


159

핵심 사양 -k2은 2에서 줄 끝까지의 모든 필드를 고려한다는 의미입니다. 그래서 Villamor 44전에 끝납니다 Villamor 50. 이 두 개가 같지 않기 때문에 첫 번째 비교는 sort -k2 -k1두 줄을 구별하기에 충분하며 두 번째 정렬 키 -k1는 호출되지 않습니다. 두 빌라 모어의 나이가 같다면 -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...)가 더 이상 적용되지 않으므로 키별 플래그와 전역 플래그를 혼합하지 않는 것이 좋습니다.


6
니가 끝냈어. -k1을 지정하면 필드 1이 기본 필드 구분 기호 (공백)로 끝나는 필드 1 사용을 의미한다고 가정했습니다 (위험한 일). 그러나 명확하게 지적했듯이 k 옵션은 단일 필드 일 수도 있고 아닐 수도있는 키의 시작 및 중지 지점을 지정해야합니다. 귀하의 솔루션은 완벽하게 작동하며, 더 중요한 것은 왜 그렇게되는지 분명합니다. 많은 감사합니다.
Harry

이것은 거대하다. KEYDEF에 대한 다른 많은 소스는 각 정렬 단계에서 고려되는 열을 제한하는 형식으로 COMMA의 중요성을 강조하지 않고 -k1 -k2에 대해 이야기합니다. 나는이 답변을 찾을 때까지 몇 시간 동안 붙어있었습니다. 그리고 맨 페이지는 여기에 혼란입니다. "시작 및 중지"위치는 쉼표 표기법으로 지정되어 있다고 설명하지 않습니다. 감사합니다!
Jason Rohrer

16

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.

4
이 이상한 표기법을 설명해 주시겠습니까?
scai

1
덕분에 올바른 방향으로 생각하게되었습니다. 감사합니다. 그러나 두 번째 -k에 대한 중지 지점을 지정할 필요는 없습니다. 즉 -k2,2 -k1,1 그렇지 않으면 정지 점이 줄의 끝으로 간주됩니까?
Harry

@TonyBedford, 맞습니다. 그러나 정지 위치를 지정하지 않으면 현재 입력의 결과가 변경되지 않지만 동일한 필드 2와 1을 가진 여러 줄이있는 경우 일관성을 유지하므로 마지막 -k을 최대한 많이 포함하는 것이 좋습니다.
manatwork

1
@manatwork 그럴 필요는 없다. 지정된 모든 필드가 동일 sort하게 비교되면 전체 행을 비교합니다. 또는 GNU sort를 사용 -s하면 안정적인 정렬에 사용할 수 있습니다 .
augurar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.