Pergunta

Eu tenho um conjunto de dados com o seguinte formato:

foo<tab>1.00<space>1.33<space>2.00<tab>3

Agora eu tentei classificar o arquivo com base no último campo de cada vez menos. Eu tentei os seguintes comandos, mas não foi resolvido como esperávamos.

$ sort -k3nr file.txt  # apparently this sort by space as delimiter

$ sort -t"\t" -k3nr file.txt
  sort: multi-character tab `\\t'

$ sort -t "`/bin/echo '\t'`" -k3,3nr file.txt
  sort: multi-character tab `\\t'

O que é o caminho certo para fazê-lo?

Aqui está a dados de amostra .

Foi útil?

Solução

Usando o bash , isso vai fazer o truque:

$ sort -t$'\t' -k3 -nr file.txt

Observe o cifrão na frente da string entre aspas simples. Você pode ler sobre -lo nas seções ANSI-C Citando do o bash página homem .

Outras dicas

Por padrão, o delimitador de campo é não-branco para a transição em branco para que guia deve funcionar muito bem.

Base No entanto, as colunas são indexados 1 e base de 0 para que você provavelmente vai querer

sort -k4nr file.txt

para File.txt tipo por coluna 4 numericamente na ordem inversa. (Embora os dados em questão tem ainda 5 campos para o último campo seria índice 5).

Você precisa colocar um caractere real guia após o -t \ e para fazer isso em uma concha que você bateu ctrl-v e, em seguida, o caractere de tabulação. A maioria das conchas Eu usei apoio este modo de entrada guia literal.

Cuidado, porém, porque copiando e colando a partir de outro lugar, geralmente não preserva guias.

A solução $ não funcionou para mim. No entanto, por realmente colocando o próprio caractere de tabulação no comando se: tipo -t '' -k2

canalizá-lo por algo como awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. Isso vai mudar os espaços para guias.

Em dados gerais de manutenção como este não é uma grande coisa a fazer se você pode evitá-lo, porque as pessoas estão sempre confundindo tabulações e espaços.

Resolver o seu problema é muito simples em uma linguagem de script como Perl, Python ou Ruby. Aqui está um código de exemplo:

#!/usr/bin/perl -w

use strict;

my $sort_field = 2;
my $split_regex = qr{\s+};

my @data;
push @data, "7 8\t 9";
push @data, "4 5\t 6";
push @data, "1 2\t 3";

my @sorted_data = 
    map  { $_->[1] }
    sort { $a->[0] <=> $b->[0] }
    map  { [ ( split $split_regex, $_ )[$sort_field], $_ ] }
    @data;

print "unsorted\n";
print join "\n", @data, "\n";
print "sorted by $sort_field, lines split by $split_regex\n";
print join "\n", @sorted_data, "\n";

Eu queria uma solução para Gnu tipo no Windows, mas nenhuma das soluções acima funcionou para mim na linha de comando.

Usando indício de Lloyd, o seguinte arquivo de lote (.bat) trabalhou para mim.

Digite o caractere de tabulação dentro das aspas duplas.

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

Eu estava tendo esse problema com o tipo em cygwin em um shell bash quando se usa 'general-numérico-tipo'. Se eu especificado -t$'\t' -kFg, onde F é o número do campo, que não funcionou, mas quando eu especificado tanto -t$'\t' e -kF,Fg (por exemplo -k7,7g para o campo de 7º) não funcionou. -kF,Fg sem a -t$'\t' não funcionou.

Se você quiser torná-lo mais fácil para si mesmo, apenas com abas, substituir os espaços com guias:

tr " " "\t" < <file> | sort <options>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top