Classificando um arquivo delimitado por tabulações
-
10-07-2019 - |
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 .
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>