classificar cada campo numericamente, variando contagens de campos

classificar cada campo numericamente, variando contagens de campos

Estou tentando classificar alguns dados usando sort. Percebi que estava classificando por dígito em vez de número, então adicionei o -nsinalizador. Aparentemente, ele classifica apenas numericamente o primeiro campo. Dividir por campo é um problema, pois as linhas têm números variados de campos (e, francamente, não consigo entender seu comportamento). Aqui estão alguns dados de amostra próximos o suficiente com os quais eu estava brincando:

echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" | sort -n

Input     Want      Expect?   sort      -n        -n -k1,1 -k2,2 -k3,3 -k4,4…

b b 1     8 2       a 1       23 44     a 1       b a 1
23 44     8 15      a 7       23 9      a 7       b a 10
b 3       23 9      b a 1     8 15      b 1       b a 2
a 7       23 44     b a 2     8 2       b 10      b b 1
b b 2     a 1       b a 10    a 1       b 2       b b 10
a 1       a 7       b b 1     a 7       b 3       b b 2
b a 10    b 1       b b 2     b 1       b a 1     a 1
b b 10    b 2       b b 10    b 10      b a 10    b 1
b 1       b 3       b 1       b 2       b a 2     b 2
b a 1     b 10      b 2       b 3       b b 1     b 3
8 2       b a 1     b 3       b a 1     b b 10    a 7
b 10      b a 2     b 10      b a 10    b b 2     b 10
8 15      b a 10    8 2       b a 2     8 15      8 2
b a 2     b b 1     8 15      b b 1     8 2       8 15
23 9      b b 2     23 9      b b 10    23 44     23 9
b 2       b b 10    23 44     b b 2     23 9      23 44

Idealmente, eu gostaria de fazê-lo funcionar naquela mesma máquina, que possui GNU coreutils sort 5.93. Eu gostaria de lidar com isso com ferramentas Unix simples; Não quero apenas entregar o problema ao perl, etc. Espero um equivalente ao [imaginário]sort --numeric-sort --all-fields --actually-work

Responder1

Acho que seu problema é que você não entende o sortque está fazendo. A classificação básica é baseada em valores de caracteres ASCII, onde os números estão antes das letras maiúsculas e antes das minúsculas: '1' == 49, 'A' == 65, 'a' = 97. Isso explica a sortcoluna, onde números como '23 'é classificado antes de '8', que é antes de 'b b': o valor ASCII para '2' é 50, o valor ASCII para '8' é 56 e para 'b' é 98.

Ao classificar numericamente ( sort -n), as entradas não numéricas são classificadas pelo método regular, mas interpretadas como zero quando comparadas a números, como 23 ou 8; mas como o valor é tratado como um número, não como um valor de caractere, '8' vem antes de '23'. Portanto, as entradas alfabéticas serão classificadas antes das entradas numéricas.

Sua melhor aposta é normalizar os dados para que cada coluna tenha o mesmo tipo de valor: todos os números ou todos alfanuméricos, e classificar adequadamente.

Na última coluna (classificação por campo), ele classificará primeiro as entradas com mais campos, pois você está especificando explicitamente 4 (ou mais) campos. Então (1,2,3) seria antes de (1,2). Sem a -kopção, sort leva em consideração a linha como um todo.

Você pode ler mais informações sobre oinformações coreutils classificarpágina.

Responder2

echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" \
| sed -r 's/[a-z]/9999&/g' | sort -n -k1 -k2 -k3 | sed 's/9999//g' 
18 2
18 15
23 9
23 44
a 1
b 1
b 2
b 3
a 7
b 10
b a 1
b b 1
b a 2
b b 2
b a 10
b b 10

É isso que você quer? Classificar numericamente, se for numérico, e números antes de outros caracteres?

Eu prefixo cada String com um número alto, para colocar as Strings por último, classificando, e removo os números altos (9999) no final.

Responder3

Com o benefício proporcionado por alguns anos de desenvolvimento, sort -Vproduz sort 8.26apenas o resultado desejado:

$ echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n8 2\nb 10\n8 15\nb a 2\n23 9\nb 2" \
   | sort -V
8 2
8 15
23 9
23 44
a 1
a 7
b 1
b 2
b 3
b 10
b a 1
b a 2
b a 10
b b 1
b b 2
b b 10

informação relacionada