정렬에서는 행을 올바르게 정렬하기 위해 파이프 "|"를 사용하지 않습니다.

정렬에서는 행을 올바르게 정렬하기 위해 파이프 "|"를 사용하지 않습니다.

간단한 파이프로 구분된 데이터를 정렬하려고 합니다. 그러나 정렬은 실제로 정렬이 아닙니다. 헤더 행이 맨 아래로 이동하지만 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

그러나 나는 이것이 필요하다고 생각하지 않습니다. 정렬이 정렬되지 않는 이유는 무엇입니까?

답변1

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"

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

그러나 이는 en_US(ISO에서 파생됨)에 대한 기본 규칙이 다음과 같기 때문입니다.

$ 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.

답변2

아쉬운 점은 24그 사이의 위치에서 움직이지 않는다는 것입니다 241. 두 번째 필드는 로 시작합니다 1. 4두 번째 필드에서 선행 정렬을 시도하면 24아래로 이동되므로 달리 명시하지 않는 한 sort무시되는 것 같습니다. |노력하다 sort -n...

답변3

-n, --numeric-sort 문자열 숫자 값을 기준으로 비교

210
23

-n이 없으면 텍스트의 210이 내 문자이기 때문에 23보다 앞서게 됩니다.

관련 정보