유닉스 정렬을 사용하여 사용자 정의 정렬을 수행하는 방법은 무엇입니까?


11

유닉스 정렬을 사용하여 쉼표로 구분 된 파일을 여러 열로 정렬하고 있습니다. 지금까지 데이터를 숫자 또는 알파벳 순서로 정렬하는 데 완벽하게 작동했습니다.

정렬 전의 예제 파일 :

C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

파일을 정렬하십시오. $ sort -t ',' -k 2,2 -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

정렬 된 결과 :

A,Bahamas,Bahamas,Nassau,f,2
A,Canada,QC,Montreal,f,2
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1

문제는 다음과 같습니다. 사용자 지정 정렬을 기준으로 2 열을 정렬하고 싶습니다. 즉, 미국을 먼저, 캐나다를, 바하마를 원한다는 것을 의미합니다.

원하는 정렬 :

A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2

유닉스 정렬에 맞춤 정렬 순서를 전달하여 적용 할 수있는 방법이 있습니까? 다음과 같은 것 : $ sort -t ',' -k 2,2:'United States, Canada, Bahamas' -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

감사!


3
이 세 값의 경우 알파벳 순서를 반대로 바꾸고 싶습니다. 일반적인 경우 이름을 정렬 순서 번호에 매핑 한 다음 정렬 순서 번호를 사용하여 정렬해야합니다. 또는 스크립팅 언어로 가십시오 ... 한 가지 가능성은 join명령이지만 많은 정렬로 끝날 수 있습니다. 입력 파일을 join한 순서로 정렬 한 다음 sort다시 사용 하여 데이터를 입력해야합니다. 다른 순서 (및 정렬 순서 열을 사후 정렬 단계로 잃음).
Jonathan Leffler

예제 입력 에서 마지막 줄 t대신에 없어야 f합니까?
Lev Levitsky

레프 : 그렇습니다. 내 잘못이야; 너무 많은 잘라 내기 및 붙여 넣기 (실제 데이터 세트가 훨씬 커서 실수로 잘못된 행을 가져옴).

귀하의 데이터와 일치하도록 답변을 업데이트했습니다.
Lev Levitsky

답변:


8

다른 답변과 의견은 일반적인 질문에 대한 답변입니다. 구현 방법은 다음과 같습니다.

$ cat order
Bahamas,3
Canada,2
United States,1

$ cat data
C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

$ sort -t, -k2 data | join -t, -11 -22 order - | sort -t, -k2n -k4,5 -k6r -k7nr | cut -d, -f 3,1,4-7
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2

도와 주셔서 감사합니다. 이것은 완벽하게 작동했습니다!

@jewelia 다시 한 번 개선되었으므로 sed실제로는 필요하지 않았습니다.
Lev Levitsky

1

sort로는 그렇게 할 수 없습니다 . 이 시점에서 awk / perl / your-language-of-choice에 도달해야합니다 . 그래도 퍼지 할 수 있습니다. 예를 들어, sed를 사용하여 "United States"를 0으로, "Canada"를 1로, "Bahamas"를 2로 변경 한 다음 해당 열에 대해 숫자 정렬을 수행 한 다음 다시 sed 할 수 있습니다. 또는 "United States"를 "United States, 0"등으로 변경하고 추가 열을 기준으로 정렬 한 다음 폐기하십시오.


0

방금 csort라는 도우미 를 작성하여 쉽게 할 수 있도록했습니다. 행 내에서 하위 문자열 또는 정규식 일치를 기반으로 선택한 값이 각 행 앞에 붙습니다.

$ csort -t, '2=United States' X 2=Canada Y 2=Bahamas Z < tmp.csv | \
sort -t, -k1,1 -k3,3 -k4,4 -k5,5 -k6,6r -k7,7nr
X,A,United States,MA,Boston,f,0
X,B,United States,NY,New York,f,5
X,A,United States,NY,New York,f,1
X,C,United States,WA,Tacoma,f,1
Y,A,Canada,QC,Montreal,f,2
Z,A,Bahamas,Bahamas,Nassau,f,2

2=STR표기 수단 "경기는 두 번째 필드가 동일한 경우 STR".

그런 다음 cut -c3-접두사를 제거하기 위해 출력을 선택적으로 파이프 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.