Classificar com base na terceira coluna

108

Estou enfrentando um enorme arquivo de 4 colunas. Gostaria de exibir o arquivo classificado no stdout com base em sua terceira coluna:

cat myFile | sort -u -k3

Isso é suficiente para realizar o truque?

    
por user1058398 10.12.2013 / 12:13

4 respostas

135
sort -k 3,3 myFile

exibiria o arquivo classificado pela coluna 3 rd assumindo que as colunas são separadas por sequências de espaços em branco (caracteres ASCII SPC e TAB no código de idioma POSIX / C), de acordo com a ordem de classificação definida por a localidade atual.

Observe que os espaços em branco iniciais são incluídos na coluna (o separador padrão é a transição de um não em branco para um em branco), que pode fazer diferença em localidades onde os espaços não são ignorados Para fins de comparação, use a opção -b para ignorar os espaços em branco iniciais.

Note que é completamente independente do shell (todas as shells analisariam a linha de comando da mesma forma, shells geralmente não possuem o comando sort embutido).

-k 3 é classificar na parte das linhas começando com a coluna 3 rd (incluindo os espaços em branco iniciais). Na localidade C, porque os caracteres space e tab classificam antes de todos os caracteres imprimíveis, isso geralmente lhe dará o mesmo resultado que -k 3,3 (exceto linhas que possuem um terceiro campo idêntico),

-u é para reter apenas uma das linhas se houver vários tipos idênticos (é aí que a chave de ordenação ordena a mesma coisa (isso não é necessariamente o mesmo que sendo igual a )).

cat é o comando para con cat enate. Você não precisa disso aqui.

Se as colunas estiverem separadas por outra coisa, você precisará da opção -t para especificar o separador.

Exemplo de arquivo a

$ cat a
a c c c
a b ca d
a b  c e
a b c d

com -u -k 3 :

$ echo $LANG
en_GB.UTF-8

$ sort -u -k 3 a
a b ca d
a c c c
a b c d
a b  c e

As linhas 2 e 3 têm a mesma terceira coluna, mas aqui a chave de classificação é da terceira coluna até o fim da linha, então -u retém ambas. ␠ca␠d classifica antes de ␠c␠c porque espaços são ignorados na primeira passagem da minha localidade, cad ordena antes de cc .

$ sort -u -k 3,3 a
a b c d
a b  c e
a b ca d

Acima apenas um é retido para aqueles em que a terceira coluna é ␠c . Observe como aquele com ␠␠c (2 espaços à esquerda) é retido.

$ sort -k 3 a
a b ca d
a c c c
a b c d
a b  c e
$ sort -k 3,3 a
a b c d
a c c c
a b  c e
a b ca d

Veja como a ordem de a b c d e a c c c está invertida. No primeiro caso, porque ␠c␠c ordena antes de ␠c␠d , no segundo caso, porque a chave de classificação é a mesma ( ␠c ), a última comparação de resort que compara as linhas em puts completas a b c d before a c c c .

$ sort -b -k 3,3 a
a b c d
a b  c e
a c c c
a b ca d

Depois de ignorarmos os espaços em branco, a chave de ordenação das 3 primeiras linhas é a mesma ( c ), então eles são classificados pela última comparação de recurso.

$ LC_ALL=C sort -k 3 a
a b  c e
a c c c
a b c d
a b ca d
$ LC_ALL=C sort -k 3,3 a
a b  c e
a b c d
a c c c
a b ca d

Na localidade C, ␠␠c ordena antes de ␠c , pois há apenas uma passagem lá, em que os caracteres (em seguida, bytes únicos) são classificados com base no valor do ponto de código (onde o espaço tem um código inferior a c ) .

    
por 10.12.2013 / 12:25
4

Se você entender "coluna" como no arquivo de texto (quarto caractere), então sim, sua solução deve funcionar (ou mesmo sort -u -k3 myFile para permitir que sort realize algumas magias para economia de memória com acesso aleatório). Se você entender "coluna" como no banco de dados - uma entidade inteira de dados seguida por um separador e largura de coluna variável, você precisará de algo mais sofisticado, por exemplo, isso classifica ls -l por tamanho

      ls -l |awk '{print $5 " " $0;}'| sort -n | cut -d " " -f 2-

(que é equivalente a ls -lS trivial, mas serve bem ao exemplo)

    
por 10.12.2013 / 12:35
1
sort -g -k column_number 

é o comando certo para classificar qualquer lista com caracteres numéricos usando uma coluna específica

    
por 05.06.2017 / 05:31
1

Você pode usar a biblioteca de Velud do awk:

#!/usr/local/bin/velour -f
{
  q[NR] = $3
  z[NR] = $0
}
END {
  a_sort_by(q, z)
  io_puts(q)
}
    
por 14.01.2018 / 16:12

Tags