유닉스 정렬로 여러 키 정렬


137

1-n 키로 정렬 해야하는 잠재적으로 큰 파일이 있습니다. 이러한 키 중 일부는 숫자 일 수 있고 일부는 아닐 수 있습니다. 이것은 너비가 고정 된 컬럼 파일이므로 분리 문자가 없습니다.

유닉스 정렬로 이것을 수행하는 좋은 방법이 있습니까? 하나의 키로 '-n'을 사용하는 것만 큼 간단합니다. 매뉴얼 페이지를 읽고 Google을 간략하게 검색했지만 좋은 예를 찾지 못했습니다. 이것을 달성하려면 어떻게해야합니까?

참고 : 파일 크기 때문에 Perl을 배제했습니다. 최후의 수단이 될 것입니다.


예제 데이터의 한두 줄은 예제 명령 줄을 만드는 데 실제로 도움이됩니다. 또한 "1-n"키는 가변 개수의 키로 정렬해야한다는 의미입니까? 스크립팅없이 그렇게하는 것은 재미있을 것입니다 ...
Ken Gentle

1-n 기능을 활성화하기 위해 sort 명령 주위에 PHP 래퍼가 있습니다.
Chris Kloberdanz

답변:


69

-k옵션 (또는 --key=POS1[,POS2])을 사용하십시오 . 여러 번 나타날 수 있으며 각 키에는 전역 옵션 (예 : n숫자 정렬)이있을 수 있습니다.


7
정렬 매뉴얼 페이지에서 : "POS는 F [.C] [OPTS]입니다. 여기서 F는 필드 번호이고 C는 필드의 문자 위치이며 둘 다 원점 1입니다." 전체 설명서는 매뉴얼 페이지를 참조하십시오.
Adam Rosenfield

49
당신이 미쳤 으면 안드라스의 답변을 참조하십시오.
ron

1
위의 두 의견은 정확하고 부가 적입니다. 고마워요
Ken Gentle

314

그래도 조심하세요 :

파일을 주로 필드 3을 기준으로 정렬하고 두 번째로 필드 2를 기준으로 정렬하려면 다음을 수행하십시오.

sort -k 3,3 -k 2,2 < inputfile

이것이 아닙니다 : sort -k 3 -k 2 < inputfile 필드 3의 시작 부분에서 줄의 끝까지 (파일은 잠재적으로 고유 한) 문자열로 파일을 정렬합니다.

-k, --key=POS1[,POS2]     start a key at POS1 (origin 1), end it at POS2
                          (default end of line)

8
삶의 변화. 감사.
davidtbernal

2
으악! 이전에는 위의 첫 번째 답변 만 보았 기 때문에 스크립트를 수정해야합니다 ... 스크립트 출력에 아직 의존하지 않은 좋은 점이 있습니다 ....
Wildcard

좋은! 이제 필드 3을 숫자로 정렬하고 역으로 정렬하고 필드 2를 숫자가 아닌 일반 (오름차순) 정렬하려면 어떻게해야합니까? :)
Arun

2
@Arun POS는 매뉴얼 페이지 끝에 설명되어 있습니다. 다음과 같이 필드 번호에 순서 옵션을 추가하면됩니다.sort -k 3,3nr -k 2,2
andras

1
아아. 무엇 반 직관적 인 인터페이스 : -k2해야 -k2,2하고 뒤에 쉼표 -k2,'라인이든의 마법 기본 끝'이어야한다.
android.weasel

94

-k 옵션은 원하는 것입니다.

-k 1.4,1.5n -k 1.14,1.15n

첫 번째 필드에서 문자 위치 4-5를 사용하고 (고정 너비의 경우 하나의 필드 임) 첫 번째 키로 숫자 순으로 정렬합니다.

두 번째 키는 첫 번째 필드의 문자 14-15입니다.

(편집하다)

예 (내가 가지고있는 것은 DOS / cygwin 만 편리합니다) :

dir | \cygwin\bin\sort.exe -k 1.4,1.5n -k 1.40,1.60r

데이터 :

12/10/2008  01:10 PM         1,564,990 outfile.txt

월 번호 (pos 4-5)를 기준으로 디렉토리 목록을 숫자 순으로 정렬 한 다음 filename (pos 40-60)을 기준으로 역순으로 정렬합니다. 탭이 없으므로 정렬 할 모든 필드 1입니다.


입력 데이터에 공백이없는 경우 하나의 필드입니다. 그럼에도 불구하고 당신의 모범은 유용합니다.
Jonathan Leffler

정정 사항 : 입력 데이터에 / tabs /가없는 경우. DOS의 'dir'명령 출력에는 탭이 없습니다.
클린턴 피어스

맨 페이지에서 사용 방법을 찾는 것이 거의 불가능하고 다른 답변에서는 언급하지 않았으므로 옵션 (숫자, 역)을 사용하는 방법에 대한 예제는 매우 유용합니다. 나는 이것을 위해 +2 할 수 있기를 바랍니다. ;)
msb

22

다음은 csv 파일의 다양한 열을 숫자 및 사전 순서, 열 5 이후 및 사전 순서로 정렬하는 방법입니다.

~/test>sort -t, -k1,1n -k2,2n -k3,3d -k4,4n -k5d  sort.csv
1,10,b,22,Ga
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C

~/test>cat sort.csv
2,3,a,9,C
2,2,b,20,F
2,2,c,19,Gb,hj
2,2,c,19,Gb,hi
2,2,c,19,Ga
2,2,b,22,Ga
1,10,b,22,Ga

-k1,1n은 1 열에서 시작하고 1 열에서 끝나는 숫자를 의미합니다. 아래에서 수행 한 경우 1, 2 열을 연결하면 1,10이 110으로 정렬됩니다.

~/test>sort -t, -k1,2n -k3,3 -k4,4n -k5d  sort.csv
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C
1,10,b,22,Ga

1
이것은 열마다 다른 스위치를 사용하는 방법을 보여주기 때문에 가장 좋은 대답입니다.
xaxa

12

나는 당신의 경우를 믿습니다

sort -t@ -k1.1,1.4 -k1.5,1.7 ... <inputfile

더 잘 작동합니다. @는 필드 구분 기호이므로 아무 곳에 나 나타나지 않는 문자인지 확인하십시오. 입력은 하나의 열로 구성된 것으로 간주됩니다.

편집 : 분명히 clintp는 이미 비슷한 대답을하였습니다. 죄송합니다. 그가 지적했듯이 플래그 'n'과 'r'은 모든 -k .... 옵션에 추가 될 수 있습니다.


docs gnu.org/software/coreutils/manual/html_node/… 에 따른 기본 구분 기호 는 공백이지만 필드 수는 예상과 다른 경우가 있습니다. LC_CTYPE 로케일 설정으로 인해 다른 사람들이 여기에서 말한 것 같습니다. 의심스러운 경우 줄의 시작부터 계산하십시오!
브래드 드레

5

-s스위치를 사용 하여 정렬을 안정화하기 위해 동일한 순위의 라인이 출력에서 ​​원래의 상대 순서를 유지하도록하는 것도 바람직합니다.


2

sort를 사용할 때 핵심 비교 순서에 영향을 미치는 로케일에주의를 기울이려면 몇 가지 팁을 추가하고 싶습니다. 일반적으로 LC_ALL = C를 사용하여 원하는 로캘을 만듭니다.


LC_ALL = C도 상당히 속도를 높일 수 있습니다!
mat kelcey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.