Como ordenar a string que combina com string + numérico usando o script bash?

24

Estes são os dados que eu quero classificar. Mas sort trata o numérico como string, os dados não são classificados como eu esperava.

/home/files/profile1
/home/files/profile10
/home/files/profile11
/home/files/profile12
/home/files/profile14
/home/files/profile15
/home/files/profile16
/home/files/profile2
/home/files/profile3
/home/files/profile4
/home/files/profile5
/home/files/profile6
/home/files/profile7
/home/files/profile8
/home/files/profile9

Eu quero classificar isso para

/home/files/profile1
/home/files/profile2
/home/files/profile3
/home/files/profile4
/home/files/profile5
/home/files/profile6
/home/files/profile7
/home/files/profile8
/home/files/profile9
/home/files/profile10
/home/files/profile11
/home/files/profile12
/home/files/profile14
/home/files/profile15
/home/files/profile16

Existe um bom caminho pelo script bash? Eu não posso usar o script ruby ou python aqui.

    
por user760548 26.06.2012 / 12:27

3 respostas

21

Você pode usar um caractere sentinela temporário para delimitar o número:

$ sed 's/\([0-9]\)/;/' log | sort -n -t\; -k2,2 | tr -d ';'

Aqui, o caractere sentinela é ';' - não deve ser parte de qualquer nome de arquivo que você queira classificar - mas você pode trocar o ';' com qualquer personagem que você gosta. Você tem que alterar as partes sed , sort e tr , de acordo com isso.

O canal funciona da seguinte maneira: O comando sed insere o sentinel antes de qualquer número, o comando sort interpreta o sentinel como delimitador de campo, classifica com o segundo campo como chave de classificação numérica e o comando tr remove o sentinel sentinela novamente.

E log denota o arquivo de entrada - você também pode enviar sua entrada para sed .

    
por 26.06.2012 / 12:34
41

Isso é muito semelhante a esta pergunta . O problema é que você tem um campo alfanumérico em que você está classificando e -n não trata isso de maneira sensata, embora a classificação de versão ( -V ) o faça. Assim use:

sort -V

Note que este recurso é atualmente suportado pelas implementações de classificação GNU, FreeBSD e OpenBSD.

    
por 26.06.2012 / 13:57
7

Se todos os seus nomes de arquivo tiverem o mesmo prefixo antes da parte numérica final, ignore-o ao ordenar:

sort -k 1.20n

(20 é a posição do primeiro dígito. É um mais o comprimento de /home/files/profile .)

Se você tiver várias partes não numéricas diferentes, insira uma sentinela .

    
por 27.06.2012 / 00:04