Classifique campos separados por vírgula em cada linha por valor numérico

6

Eu tentei isso:

$ echo "2,3435,1" | sort -n
2,3435,1

$ sort -t',' -n test_sort.txt
kill,gill,burger
110,20,30,13

$ cat test_sort.txt
110,20,30,13
kill,gill,burger

Por que o meu comando sort não funciona?

Meu comando sort desejado deve funcionar assim:

$sort -t',' -n test_sort.txt  
110,13,20,30,burger,gill,kill

RESPOSTA: tr, '\ n' < a | sort -n | pasta -sd, -

"Graças a Stéphane Chazelas"

    
por sij 02.07.2014 / 16:39

4 respostas

9

sort opera em linhas inteiras. Por padrão, ele classifica todo o conteúdo dessa linha, mas -k pode ser usado para classificar um ou mais campos nessas linhas. -t pode ser usado para alterar o delimitador entre campos. Não consigo pensar em um caso em que usar -t sem usar -k faça sentido.

Seu segundo comando, que é equivalente a:

printf "%s\n%s\n" "110,20,30,13" "kill,gill,burger" | sort -t',' -n

produz:

kill,gill,burger
110,20,30,13

Qual é o que eu esperaria. -t',' não tem efeito porque está alterando o delimitador de campo quando você não disse que a classificação funcione em campos individuais e, portanto, k é classificado antes de 1 porque seu valor numérico é 0 (e você solicitou a ordem numérica usando -n ).

    
por 02.07.2014 / 16:46
6

Classificar funciona por linha, não em campos dentro de uma linha.

Por padrão, ele é classificado com base no primeiro caractere na linha e continua a partir daí. Mas você também pode classificar "chaves" diferentes do começo. Isso é útil quando você deseja classificar o sobrenome ou um valor numérico no final da linha, ou assim por diante. É para isso que a -t sinaliza - não não quebrará as linhas individuais e classificará dentro delas.

Se é isso que você quer fazer, consulte Classificar campos in-line

    
por 02.07.2014 / 16:45
1

Será mais fácil com perl :

$ perl -F',' -anle '
    BEGIN { $" = "," }
    print "@{[sort {$a <=> $b} @F]}"
' file 
13,20,30,110
kill,gill,burger

Esta única linha de classificação contém números. Se você quiser que as linhas de classificação contenham uma string como sort -n , tente:

$ $ perl -MPOSIX=isdigit -F',' -anle '
BEGIN { $" = "," }
print "@{[ sort { isdigit($a)
              ? ($a <=> $b)
              : ($a cmp $b)
              } @F
        ]}"
' file
13,20,30,110
burger,gill,kill

Essa abordagem ainda funciona apenas se o like contiver apenas string, falhar com o like contém string mista, números como kill,gill,20 .

    
por 03.07.2014 / 04:14
0

A classificação por vírgulas é algo possível:

echo "a,b,z,sa,b,z,a,d,2,4a,a,dx" | tr , "\n" | sort

Saídas

2
4a
a
a
a
b
b
d
dx
sa
z
z

E se você quiser de volta em uma linha:

echo "a,b,z,sa,b,z,a,d,2,4a,a,dx" | tr , "\n" | sort | tr "\n" ,
    
por 27.05.2017 / 00:29