A ordenação não é consistente usando o comando Unix 'sort'

0

Estou executando o comando:

zcat [File] | sed "1d" | sort -t $'\xE7' -k [field to be sorted] > [file].sorted

Quando eu executo isso no Arquivo A, classificando no campo 1, recebo o seguinte resultado:

11622400 , abe, def
11622401 , abe, def
11622402 , bbabe, def
11622403 , ddabe, def
11622404 , acdc, dere
11622405 , ddabe, bere
11622406 , abe, fgh
11622407 , adbed, ddee
11622408 , adbe, def
11622409 , abdde, def
1162240 , abe, deed
11622410, def,dede

Mas quando eu executo o mesmo comando no arquivo 2 classificando no campo 2, eu entendo:

1162303, 116224
1162420, 1162240
11623062, 11622400
11623063, 11622401
11623064, 11622402
11623065, 11622403
11623066, 11622404
11623067, 11622405
11623068, 11622406
11623069, 11622407
11623070, 11622408
11623071, 11622409
1162421, 1162241
11623072, 1162410

Por que não está classificando da mesma maneira? O primeiro exemplo parece errado, a segunda linha da parte inferior deve estar no topo.

Estou tentando unir esses arquivos com o comando Unix join , mas como eles não estão sendo ordenados da mesma maneira, isso está perdendo muitos registros.

Qual é o motivo para esse problema?

    
por mattm123 25.10.2010 / 14:58

3 respostas

2

O motivo pelo qual você está obtendo esses resultados é que sua classificação não é numérica, ela é baseada em valores canônicos das colunas.

Existe uma opção de linha de comando para ordenar numericamente, isto é o que você quer (digite 'man sort' na sua barra do google)

    
por 22.10.2010 / 16:53
2

Há algo errado com sua pergunta: você afirma usar $'\xE7' como o separador de registro, mas esse byte não aparece no arquivo. Se este é realmente o comando que você executou e estas são realmente suas saídas, o arquivo A foi classificado com base na linha inteira e o arquivo B foi classificado aleatoriamente (todos os campos 2 estão vazios e sort não é estável por padrão). No entanto, como o arquivo 2 parece classificado no segundo campo " , " - separado em sua saída do arquivo B, eu acho que isso é um bug na sua pergunta e seu código usou um espaço ou vírgula como separador ou seus dados contêm o byte E7 onde seus dados aqui tem uma vírgula e um espaço.

Se você passar uma opção -t para definir um separador para classificação, você deverá passar o mesmo separador para join . Em qualquer caso, você precisa informar join de quais colunas ingressar. Por exemplo:

<a.input sort -t $'\xE7' -k1 >a.sorted
<b.input sort -t $'\xE7' -k2 >b.sorted
join -1 1 -2 2 -t $'\xE7' a.sorted b.sorted >joined

Além disso, como " 11622409 , " aparece antes de " 1162240 , " em sua saída do arquivo A, parece que você está executando sort em uma localidade que produz resultados que se aproximam das regras de classificação humana se aproximando, porque sort não é refinado o suficiente para corresponder às regras bastante complicadas usadas na tipografia séria). Você obterá resultados menos surpreendentes se alterar sua localidade para uma que produza resultados adequados para o consumo do computador. Na prática, isso significa que sua configuração de LC_COLLATE deve ser C (ou seu sinônimo POSIX ). (Qualquer outro local tende a quebrar scripts que usam sort , embora o seu deva, de fato, estar ok.) Exemplo:

$ cat a
11622409 , abdde, def
1162241 , abe, deed
11622410, def,dede
$ LC_COLLATE=en_US sort <a
11622409 , abdde, def
11622410, def,dede
1162241 , abe, deed
$ LC_COLLATE=C sort <a
11622409 , abdde, def
1162241 , abe, deed
11622410, def,dede

Se você estiver executando join na mesma localidade que sort , tudo bem. Note que sort produz a saída ordenada lexically , não numericamente classificada; mas é isso que você quer como entrada para join .

    
por 25.10.2010 / 22:14
0

Tente:

zcat [File] | sed "1d" | sort -tn $'\xE7' -k [field to be sorted] > [file].sorted
    
por 25.10.2010 / 23:17

Tags