2009-06-24 8 views
134

que tiene un archivo con el siguiente formato:Unix Ordenar con Tab delimitador

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

Ahora me trataron de ordenar el archivo basado en el último campo cada vez menos. Intenté los siguientes comandos pero no se ordenó como esperábamos.

$ 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' 

¿Cuál es la forma correcta de hacerlo?

Aquí está el sample data.

Respuesta

242

Usando fiesta, esto va a hacer el truco:

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

Aviso el signo de dólar en frente de la cadena entre comillas simples. Puede leer acerca de en el ANSI-C Quoting sections of the bash man page.

+0

[Usar] (https://stackoverflow.com/a/1250279/4970442) ''"' "'' para usarlo dentro de un alias. –

+0

¿Puedes mostrar cómo pasar este delímetro para ordenar dentro de un comando awk? como en 'awk' {print $ 0 | "ordenar -nr"> "archivo de salida"} 'archivo de datos', excepto con un delómetro de pestañas escapadas enviado al comando de ordenación. – Merlin

1

pídalo a través de algo así como awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. Esto cambiará los espacios en pestañas.

+0

@MB: Necesito mantener el espacio intacto. – neversaint

+1

Sin duda, hay una forma más limpia de hacerlo, pero nada le impide pasarla por awk, cambiar los espacios a pestañas, ordenar los datos y volver a conectarlos nuevamente, volviendo a cambiar las pestañas en espacios. –

+1

Esto no funcionará si hay una combinación de pestañas y espacios que desea conservar. –

9

De forma predeterminada, el delimitador de campo no está en blanco para la transición en blanco, por lo que la pestaña debería funcionar bien.

Sin embargo, las columnas se indexan base 1 y la base 0 por lo que es probable que desee

sort -k4nr file.txt 

para ordenar por la columna 4 archivo.txt numéricamente en orden inverso. (Aunque los datos en la pregunta tienen incluso 5 campos, el último campo sería el índice 5.)

+4

Esto solo funcionará si el número de espacios entre los campos separados por tabuladores es el mismo para todas las líneas de entrada. –

1

En general, mantener datos como este no es una gran cosa que hacer si se puede evitar, porque las personas siempre están confundiendo pestañas y espacios

Resolver su problema es muy sencillo en un lenguaje de scripting como Perl, Python o Ruby. Aquí hay un código de ejemplo:

#!/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"; 
2

La solución $ no funcionó para mí. Sin embargo, al tener que poner el propio carácter de tabulación en el comando hizo: tipo -t '' -K2

+0

Use '' para insertar la pestaña en caso de que la tecla de tabulación se use para completar automáticamente en su caparazón. –

1

quería una solución para GNU especie en Windows, pero ninguna de las soluciones anteriores dio por mí en la línea de comandos .

Usando la pista de Lloyd, el siguiente archivo por lotes (.bat) funcionó para mí.

Escriba el carácter de tabulación dentro de las comillas dobles.

C:\>cat foo.bat 

sort -k3 -t" " tabfile.txt 
+1

Sí, el truco aquí es ponerlo en un archivo .bat; de lo contrario, no funcionará –

0

Estaba teniendo este problema con el género en cygwin en un shell bash al usar 'general-numic-sort'. Si especifiqué -t$'\t' -kFg, donde F es el número de campo, no funcionó, pero cuando especifiqué tanto -t$'\t' como -kF,Fg (por ejemplo, -k7,7g para el 7mo campo) funcionó. -kF,Fg sin el -t$'\t' no funcionó.

3

Debe poner un carácter de tabulación real después de -t \ y para hacer eso en un intérprete de comandos pulse ctrl-v y luego el carácter de tabulación. La mayoría de los proyectiles que he usado admiten este modo de entrada de tabulación literal.

Tenga cuidado, sin embargo, porque copiar y pegar desde otro lugar generalmente no conserva las pestañas.

Cuestiones relacionadas