gnu 정렬에서 --general-numeric-sort와 --numeric-sort 옵션의 차이점은 무엇입니까?


113

sort두 종류의 숫자 정렬을 제공합니다. 이것은 man 페이지에서 가져온 것입니다.

   -g, --general-numeric-sort
          compare according to general numerical value

   -n, --numeric-sort
          compare according to string numerical value

차이점이 뭐야?


17
의 전체 문서 sortman페이지가 아니라 info페이지 ( info sort)입니다.
a3nm

답변:


85

일반 숫자 정렬은 숫자를 부동 소수점으로 비교합니다. 이것은 과학적 표기법 (예 : 1.234E10)을 허용하지만 더 느리고 반올림 오류 (1.2345678은 1.2345679 이후에 올 수 있음)가 발생합니다. 숫자 정렬은 10이 9 다음에 오는 것을 알고있는 일반적인 알파벳 정렬입니다.

참조 http://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html를

'-g' '--general-numeric-sort' '--sort = general-numeric'표준 C 함수 strtod를 사용하여 숫자로 정렬하여 각 줄의 접두사를 배정 밀도 부동 소수점 숫자로 변환합니다. 이를 통해 1.0e-34 및 10e100과 같은 과학적 표기법으로 부동 소수점 숫자를 지정할 수 있습니다. LC_NUMERIC 로케일은 소수점 문자를 결정합니다. 오버플로, 언더 플로 또는 변환 오류를보고하지 마십시오. 다음 조합 순서를 사용하십시오. 숫자로 시작하지 않는 행 (모두 동일한 것으로 간주 됨). NaN (IEEE 부동 소수점 산술에서 "숫자가 아님"값)은 일관되지만 기계에 따라 다릅니다. 마이너스 무한대. 숫자 오름차순 (-0과 +0이 같음)의 유한 숫자. 플러스 무한대.

대안이없는 경우에만이 옵션을 사용하십시오. --numeric-sort (-n)보다 훨씬 느리고 부동 소수점으로 변환 할 때 정보를 잃을 수 있습니다.

'-n' '--numeric-sort' '--sort = numeric'숫자로 정렬합니다. 숫자는 각 행에서 시작하며 선택적 공백, 선택적 '-'기호 및 천 단위 구분 기호로 구분 될 수있는 0 개 이상의 숫자, 선택적으로 소수점 문자 및 0 개 이상의 숫자로 구성됩니다. 빈 숫자는 '0'으로 처리됩니다. LC_NUMERIC 로케일은 소수점 문자와 천 단위 구분 기호를 지정합니다. 기본적으로 공백은 공백 또는 탭이지만 LC_CTYPE 로케일이이를 변경할 수 있습니다.

비교는 정확합니다. 반올림 오류가 없습니다.

선행 '+'또는 지수 표기법은 인식되지 않습니다. 이러한 문자열을 숫자로 비교하려면 --general-numeric-sort (-g) 옵션을 사용하십시오.


2
감사. man 및 info 페이지에이 내용이없는 것이 이상합니다. 또한 gnu.org/software/coreutils/manual/html_node/index.html대해서도 몰랐습니다 .
Trenton

6
이 물건은 나를 위해 작동하지 않습니다. R1 R2 R10 R15와 같은 내용이있는 세 번째 열이있는 파일을 정렬하고 있습니다. 중 하나를 사용 -k3.2n하거나 -k3.2g, 그것은 정렬됩니다 R10전에 R2. 정렬은 숫자가 아닌 사전 식입니다. 두 번째 문자부터 필드를 숫자로 취급 할 것으로 예상합니다.
Kaz

6
@Kaz : sort의 주요 사양. 진정으로 비잔틴입니다-그것의 부족 : 필드 앞의 공백은 필드의 일부로 간주 되므로 char. 인덱스 1은 필드의 실제 첫 번째 문자가 아니라 필드 앞의 (첫 번째) 공백을 가리 킵니다. 문자를 추가하십시오. 색인 b을 사용하여이 문제를 수정합니다. 예 : -k 3.2bn,3( 이 경우 전역 -b 옵션이 작동 하지 않음 ). 또한 ,3두 번째 필드 인덱스가 없으면 전체 행나머지 가 사용됩니다.
mklement0

11

로케일에주의해야합니다. 예를 들어, 부동 숫자 (예 : 2.2)를 정렬하려는 반면 로케일은 쉼표 (예 : 2,2) 사용을 예상 할 수 있습니다.

이 포럼에 보고 된대로 -n 또는 -g 플래그를 사용하면 잘못된 결과를 얻을 수 있습니다.

제 경우에는 다음을 사용합니다.

LC_ALL=C sort -k 6,6n file

다음을 포함하는 6 번째 열을 정렬하려면

2.5
3.7
1.4

얻기 위해

1.4
2.5
3.7

2
LANG = C를 사용해도 -n쉼표를 천 단위 구분 기호로 인식 할 수 없습니다. "1,000"은 "1"과 동일하게 취급됩니다.
Scott

1
LC_ALL = C 여야합니다.
Stuart P. Bentley

@Scott은 : 사실, 천 단위 구분은 인식되지 않습니다 : sort사용 가장 긴 접두사 논리 : 숫자를 사용하는 것처럼 인식 라인 / 키의 가장 긴 부분을; .기수 문자로 사용하는 로케일에서는 에서 읽기가 중지됩니다 ,.
mklement0

@ StuartP.Bentley : LC_ALL=C실제로 가장 강력한 선택입니다. 그러나 LC_ALL베팅이 설정되지 않은 경우 LANG=C에도 작동합니다.
mklement0

1
좋은 지적이지만 LANG=C sort -k 6,6n file더 간단하고 환경 변수 를 특정 명령 으로 설정하는 효과를 지역화 합니다 LANG.
mklement0

0

-g허용 과학적 표기법 을 언급하는 허용되는 답변 외에도 바람직하지 않은 행동을 유발할 가능성이 가장 높은 부분을 보여주고 싶습니다.

와 함께 -g:

$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -g myfile
baa
--inf
--inf  
--inf- 
--inf--
--inf-a
--nnf
nnf--
   nnn  
tnan
zoo
   naN
Nana
nani lol
-inf
-inf--
-11
-2
-1
1
+1
2
+2
0xa
11
+11
inf

zoo여기에서 세 가지 중요한 사항을 살펴보십시오 .

  • NAN(예 : Nananani lol) 또는 -INF(단일 대시, 아님 --INF)으로 시작하는 줄은 끝으로 이동하지만 숫자 이전으로 이동합니다. 하지만 INF숫자 후 마지막으로 이동하기 때문에 그것은 무한대를 의미한다 .

  • NAN, INF-INF있는 경우를 구분 .

  • 선은 항상 양쪽에서 공백 무시 NAN, INF, -INF (에 관계없이 LC_CTYPE). 다른 알파벳은 로케일에 따라 양쪽의 공백을 무시할 수 있습니다 LC_COLLATE(예 : LC_COLLATE=fr_FR.UTF-8무시하지만 무시하지는 LC_COLLATE=us_EN.UTF-8않음).

따라서 임의의 영숫자 를 정렬하는 경우 -g. 과 과학적 표기법 비교가 정말로 필요하다면 -g알파벳과 숫자 데이터를 추출하고 개별적으로 비교를 원할 것입니다 .

일반적인 숫자 (예 1, -1:) 정렬 만 필요 하고 0x/E/+ sorting중요하지 않다고 생각되면 -n충분히 사용하십시오 .

$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -n myfile
-1000
-22
-13
-11
-010
-10
-5
-2
-1
-0.2
-0.12
-0.11
-0.1
0x1
0x11
0xb
+1
+11
+2
-a
-aa
--aa
-aaa
-b
baa
BAA
bbb
+ignore
inf
-inf
--inf
--inf  
--inf- 
--inf--
-inf--
--inf-a
   naN
Nana
nani lol
--nnf
nnf--
   nnn  
None         
uum
Zero cool
-zzz
1
1.1
1.234E10
5
11

하나의 -g-n, 인식 로케일 효과 . 당신은 지정할 수 있습니다 LC_NUMERICus_EN.UTF-8 fr_FR.UTF-8 종류 피하기 위해 -수 실패 부동 :

$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=fr_FR.UTF-8 sort -n myfile
-10
-5
-2
-1
-1.1
-1.2
-0.1
-0.11
-0.12
-0.2
-a
+b
middle
-wwe
+zoo
1
1.1

와 함께 LC_NUMERIC=en_US.UTF-8:

$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -n myfile
-10
-5
-2
-1.2
-1.1
-1
-0.2
-0.12
-0.11
-0.1
-a
+b
middle
-wwe
+zoo
1
1.1

또는 LC_NUMERIC=us_EN.UTF-8그룹 +|-|spacealpha:

$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=us_EN.UTF-8 sort -n myfile
-0.1
    a
    b
 a
 b
+b
+zoo
-a
-wwe
middle
1

이식 가능한 스크립트를 작성하려면 locale사용할 때 지정하고 싶을 것입니다 sort.

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