파이프 '|'로 줄을 정렬하지 않음으로 정렬 올바르게


17

간단한 파이프 구분 데이터를 정렬하려고합니다. 그러나 정렬은 실제로 정렬되지 않습니다. 헤더 행을 맨 아래로 이동하지만 241로 시작하는 두 행은 24로 시작하는 행으로 분할됩니다.

cat sort_fail.csv
column_a|column_b|column_c
241|212|20810378
24|121|2810172
241|213|20810376

sort sort_fail.csv
241|212|20810378
24|121|2810172
241|213|20810376
column_a|column_b|column_c

열 머리글이 파일의 맨 아래로 이동되므로 정렬이 명확하게 처리하고 있습니다. 그러나 실제 값은 예상대로 정렬되지 않습니다.

이 경우 나는 그것을 해결했다

sort sort_fail.csv --field-separator='|' -k1,1

그러나 나는 그것이 필요하지 않은 것처럼 느낍니다. 정렬이 왜 정렬되지 않습니까?


2
사용하십시오 LC_COLLATE=C sort. 기대하는 바에 따라 다음이 필요할 수도 있습니다.LC_COLLATE=C sort -t'|' -n
— mosvy

3
인용 된 값을 올바르게 처리 하는 csvsort에서 사용할 "csv 스타일"데이터를 정렬 csvkit합니다.
— Bakuriu

답변:


32

sort 로케일을 인식하므로 LC_COLLATE 설정 (LANG에서 상 속됨)에 따라 다른 결과를 얻을 수 있습니다.

$ LANG=C sort sort_fail.csv 
241|212|20810378
241|213|20810376
24|121|2810172
column_a|column_b|column_c

$ LANG=en_US sort sort_fail.csv
241|212|20810378
24|121|2810172
241|213|20810376
column_a|column_b|column_c

호출 로캘이 무엇으로 설정되어 있는지 알지 못하여 다른 결과를 얻을 수 있기 때문에 스크립트에서 문제가 발생할 수 있습니다.

스크립트가 필요한 설정을 강제하는 것은 드문 일이 아닙니다

예 :

$ grep 'LC.*sort' /bin/precat
      LC_COLLATE=C sort -u | prezip-bin -z "$cmd: $2"

이제 흥미로운 점은 |캐릭터가 이상하게 보인다는 것입니다.

그러나 ISO에서 파생 된 en_US의 기본 규칙이 있기 때문입니다.

$ grep 007C /usr/share/i18n/locales/iso14651_t1_common
<U007C> IGNORE;IGNORE;IGNORE;<j> # 142 |

이는 |문자가 무시 되고 문자가 존재하지 않는 것처럼 정렬 순서 가 됨을 의미 합니다.

$ tr -d '|' < sort_fail.csv | LANG=C sort
24121220810378
241212810172
24121320810376
column_acolumn_bcolumn_c

그리고 그것은 당신이보고있는 "예기치 않은"분류와 일치합니다.

해결 방법은 -n숫자 정렬을 사용하거나 필드 구분 기호 (사용한 것처럼)를 사용하거나 C로캘 을 사용하는 것 입니다.


매혹적인. 현지화에 대한 다른 히트를 보았지만 24 대 241의 상대적 순서에 영향을 줄 것이라고 생각했습니다.
— user10777668

7
GNU 정렬에서 특히 유용한 것은 --debug옵션인데, 이는 비교하는 데 사용되는 키 (밑줄로 표시됨)를 나타냅니다.
— Jeff Schaller

--debug로 실행하면 전체 줄에 밑줄이 생깁니다. 파이프 문자를 포함하여 정렬하면 현지화로 인해 영향을 미치지 않도록 설정됩니다. 좋은 기능이지만이 경우에는 도움이되지 않았습니다. (나는 시도했습니다)
— user10777668 17시 37 분

그것이 바로 @ user10777668이라고 언급 한 이유 sort입니다. 우리가 생각하는 문자를 멈추지 않고 전체 줄을 사용하고 있음을 나타냅니다 .
— Jeff Schaller

나는 그것이 멈추기를 기대하지 않았다. 나는 파이프 특성을 인식하고 그것을 정렬하여 24 | 1과 241을 다르게 취급하기를 기대했습니다. --debug가 어떻게 변경했는지 잘 모르겠으며 실제로는 | 가 적극적으로 파이프 문자 주도 현지화가 ingored되는 실제 문제에서 산만 한 것처럼 보인다
— user10777668

1

나를 자극하는 24것은 두 사이의 위치에서 움직이지 않는다는 것 241입니다. 두 번째 필드는로 시작합니다 1. 4두 번째 필드에서 선행 을 사용 하여 정렬을 시도하면가 24아래로 이동하므로 달리 언급하지 않는 한 sort무시합니다 |. 시도해보십시오 sort -n...


1

-n,-숫자-정렬 문자열 숫자 값에 따라 비교

210
23

-n이 없으면 문자로 210 문자가 내 문자가되므로 23보다 빠릅니다.


당신 말이 맞지만 파이프 숯이 다르다는 것을 설명하지는 않습니다. 다른 답변은 로캘로 인해 파이프가 존재하지 않는 것으로 취급되므로 다음 자리가 순서를 결정하는 것으로 나타납니다.
— Criggie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.