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


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.