sort command: -g versus -n flag

2

Qual é a diferença entre usar o comando sort com -g e -n ?

Eu tentei os dois sinalizadores com ls -la e a saída foi idêntica.

A página man diz que -g "compara de acordo com o valor numérico geral" e -n "compara de acordo com o valor numérico da string"?

Eu não entendo o que eles significam lá.

O que significa "valor numérico geral"? O que significa "valor numérico de string"?

    
por bew5 23.10.2016 / 13:50

3 respostas

3

Da página de informações de sort , a classificação -g é explicada por estes

‘-g’
‘--general-numeric-sort’
‘--sort=general-numeric’
     Sort numerically, converting a prefix of each line to a long
     double-precision floating point number.  *Note Floating point::.
     Do not report overflow, underflow, or conversion errors.  Use the
     following collating sequence:

        • Lines that do not start with numbers (all considered to be
          equal).
        • NaNs (“Not a Number” values, in IEEE floating point
          arithmetic) in a consistent but machine-dependent order.
        • Minus infinity.
        • Finite numbers in ascending numeric order (with -0 and +0
          equal).
        • Plus infinity.

     Use this option only if there is no alternative; it is much slower
     than ‘--numeric-sort’ (‘-n’) and it can lose information when
     converting to floating point.

sort -n é o tipo natural que normalmente esperamos

‘-n’
‘--numeric-sort’
‘--sort=numeric’
     Sort numerically.  The number begins each line and consists of
     optional blanks, an optional ‘-’ sign, and zero or more digits
     possibly separated by thousands separators, optionally followed by
     a decimal-point character and zero or more digits.  An empty number
     is treated as ‘0’.  The ‘LC_NUMERIC’ locale specifies the
     decimal-point character and thousands separator.  By default a
     blank is a space or a tab, but the ‘LC_CTYPE’ locale can change
     this.

     Comparison is exact; there is no rounding error.

     Neither a leading ‘+’ nor exponential notation is recognized.  To
     compare such strings numerically, use the ‘--general-numeric-sort’
     (‘-g’) option.

Verifique a resposta da Steeldriver para obter uma explicação melhor.

    
por Anwar 23.10.2016 / 14:47
6

A principal diferença está no tratamento de números que estão em notação científica . De info sort , ao usar o tipo -n (numérico)

 Neither a leading '+' nor exponential notation is recognized.  To
 compare such strings numerically, use the '--general-numeric-sort'
 ('-g') option.

Então, por exemplo, dado

$ cat file
+1.23e-1
1.23e-2
1.23e-3
1.23e4
1.23e+5
-1.23e6

então

$ sort -n file
-1.23e6
+1.23e-1
1.23e-2
1.23e-3
1.23e4
1.23e+5

enquanto

$ sort -g file
-1.23e6
1.23e-3
1.23e-2
+1.23e-1
1.23e4
1.23e+5
    
por steeldriver 23.10.2016 / 15:15
3

Em o manual sort :

  

'- n'
'- numeric-sort'
'- sort = numérico'

     

Classifique numericamente. O número começa cada linha e consiste em opcional   espaços em branco, um sinal opcional "-" e zero ou mais dígitos possivelmente   separados por separadores de milhares, opcionalmente seguido por um   caractere de ponto decimal e zero ou mais dígitos. Um número vazio é   tratado como "0". O LC_NUMERIC locale especifica o ponto decimal   caractere e separador de milhares. Por padrão, um espaço em branco é um espaço ou uma   guia, mas o LC_CTYPE locale pode mudar isso.

     

A comparação é exata; não há erro de arredondamento.

     

Nem uma notação principal "+" nem exponencial é reconhecida. Para   comparar tais cadeias numericamente, use o --general-numeric-sort   ( -g ) opção.

E

  

'- g'
'- general-numeric-sort'
'- sort = geral-numérico'

     

Classifique numericamente, convertendo um prefixo de cada linha em um longo   número de ponto flutuante de precisão dupla. Consulte ponto flutuante . Não   relatar erros de estouro, estouro ou conversão. Use o seguinte   sequência de intercalação:

     
  • Linhas que não começam com números (todas consideradas iguais).
  •   
  • NaNs (valores "Não é um número", na aritmética de ponto flutuante do IEEE) em uma ordem consistente, mas dependente da máquina.
  •   
  • Menos infinito.
  •   
  • Números finitos em ordem numérica crescente (com -0 e +0 iguais).
  •   
  • Mais infinito.
  •   

Use esta opção somente se não houver alternativa; é muito mais lento   que --numeric-sort ( -n ) e pode perder informações quando   convertendo para ponto flutuante.

Então, parece que usar -g poderia resultar em comparações incorretas devido à perda de precisão, mas, por qualquer motivo, não posso produzir um resultado como esse:

$ printf "%s\n" 1 1.23 1.234 1.2345 1.23456 1.234567 1.2345678 1.23456789 1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888878888888888 | sort -g
1
1.23
1.234
1.2345
1.23456
1.234567
1.2345678
1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888878888888888
1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
1.23456789

sort -g coloca corretamente a segunda fração longa antes da primeira, mas a diferença entre as duas está bem além da precisão de um double :

$ cat test.cpp  
#include<iostream>

using namespace std;

int main()
{
    cout << (1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888887888888888888888888888 < 1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888) << endl;
    cout << (1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888887888888888888888888888 > 1.23456788888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888) << endl;
}
$ make test     
g++     test.cpp   -o test
$ ./test        
0
0
    
por muru 23.10.2016 / 15:31