2009-06-24 13 views
134

Ho un dati con il seguente formato:Unix Ordina con Tab delimitatore

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

Ora ho cercato di ordinare i file in base all'ultimo campo sempre meno. Ho provato i seguenti comandi ma non è stato ordinato come previsto.

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

Qual è il modo giusto per farlo?

Ecco lo sample data.

risposta

242

Utilizzando bash, questo farà il trucco:

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

Avviso il simbolo del dollaro di fronte della stringa tra apici singoli. Puoi leggere lo nello ANSI-C Quoting sections of the bash man page.

+0

[Usa] (https://stackoverflow.com/a/1250279/4970442) ''' '' '' 'per usarlo all'interno di un alias. –

+0

puoi mostrare come passare questo delimitatore per ordinare all'interno di un comando awk? come in "awk" {stampa $ 0 | "sort -nr"> "outfile"} 'datafile', tranne che con un delimitatore di linguette con caratteri di escape inviato al comando sort. – Merlin

1

attraversare qualcosa come awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. Questo cambierà gli spazi in schede.

+0

@ MB: ho bisogno di mantenere lo spazio intatto. – neversaint

+1

C'è sicuramente un modo più semplice per farlo, ma nulla ti impedisce di collegarlo tramite awk, cambiare gli spazi in schede, ordinare i dati e poi reindirizzarli attraverso awk di nuovo, cambiando nuovamente le schede in spazi. –

+1

Questo non funzionerà se c'è una combinazione di schede e spazi che si desidera conservare. –

9

Per impostazione predefinita, il delimitatore di campo non è una transizione da vuota a vuota, pertanto la scheda dovrebbe funzionare correttamente.

Tuttavia, le colonne sono indicizzati base 1 e la base 0 quindi probabilmente si desidera

sort -k4nr file.txt 

per ordinare file.txt dalla colonna 4 numericamente in ordine inverso. (Anche se i dati nella domanda hanno anche 5 campi, l'ultimo campo sarebbe l'indice 5.)

+4

Funziona solo se il numero di caratteri di spazio tra i campi separati da tabulazioni è uguale per tutte le righe di input. –

1

In generale, conservare dati come questi non è una cosa grandiosa da fare se si può evitarlo, perché le persone sono sempre tabulazioni confuse e spazi.

La risoluzione del problema è molto semplice in un linguaggio di scripting come Perl, Python o Ruby. Ecco qualche esempio di codice:

#!/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 soluzione $ non ha funzionato per me. Tuttavia, in realtà mettendo il carattere di tabulazione in sé nel comando ha fatto: sorta -t '' -k2

+0

Utilizzare '' per inserire la scheda nel caso in cui il tasto tab venga utilizzato per il completamento automatico nella shell. –

1

volevo una soluzione per Gnu sorta su Windows, ma nessuna delle soluzioni di cui sopra ha lavorato per me sulla riga di comando .

Utilizzando l'indizio di Lloyd's, il seguente file batch (.bat) ha funzionato per me.

Immettere il carattere di tabulazione tra virgolette.

C:\>cat foo.bat 

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

Sì, il trucco qui è metterlo in un file .bat, altrimenti non funzionerà –

0

ero a questo problema con ordinamento in cygwin in una shell bash quando si usa 'generale numerico-ordinamento'. Se ho specificato -t$'\t' -kFg, dove F è il numero del campo, non ha funzionato, ma quando ho specificato sia -t$'\t' e -kF,Fg (ad esempio -k7,7g per il settimo campo) ha funzionato. -kF,Fg senza il -t$'\t' non ha funzionato.

3

È necessario inserire un carattere di tabulazione effettivo dopo -t \ e per farlo in una shell si preme ctrl-v e quindi il carattere di tabulazione. La maggior parte delle shell che ho usato supportano questa modalità di inserimento della scheda letterale.

Attenzione, tuttavia, poiché la copia e l'incolla da un altro posto generalmente non conserva le schede.