200 votes

Tri d'un fichier délimité par des tabulations

J'ai une donnée avec le format suivant :

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

Maintenant, j'ai essayé de trier le fichier en fonction du dernier champ de façon décroissante. J'ai essayé les commandes suivantes mais il n'a pas été trié comme prévu.

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

Quelle est la bonne façon de procéder ?

Voici le données de l'échantillon .

352voto

Lars Haugseth Points 7377

Utilisation de bash cela fera l'affaire :

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

Remarquez le signe dollar devant la chaîne de caractères entre guillemets. Vous pouvez lire à ce sujet dans le ANSI-C Citer des sections du bash page de manuel .

2 votes

Utilisez '"'"' pour l'utiliser dans un alias.

0 votes

Pouvez-vous montrer comment passer ce paramètre à sort dans une commande awk ? comme dans awk '{print $0 | "sort -nr" > "outfile" }' datafile sauf avec un délimiteur de tabulation échappé envoyé à la commande de tri.

1 votes

Utilice -g plutôt que -n si vous voulez un tri numérique. -n est cassé.

12voto

laalto Points 50581

Par défaut, le délimiteur de champ est la transition non-blanc à blanc, donc la tabulation devrait fonctionner parfaitement.

Cependant, les colonnes sont indexées en base 1 et en base 0, donc vous voulez probablement

sort -k4nr file.txt

pour trier fichier.txt par la colonne 4 numériquement dans l'ordre inverse. (Bien que les données de la question aient 5 champs pairs, le dernier champ serait donc l'indice 5).

7 votes

Cela ne fonctionnera que si le nombre de caractères d'espacement entre les champs séparés par une tabulation est le même pour toutes les lignes de saisie.

1voto

Je voulais une solution pour Gnu sort sous Windows, mais aucune des solutions ci-dessus n'a fonctionné pour moi en ligne de commande.

En utilisant l'indice de Lloyd, le fichier batch suivant (.bat) a fonctionné pour moi.

Tapez le caractère de tabulation entre les guillemets.

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

1 votes

Le truc, c'est de le mettre dans un fichier .bat, sinon ça ne marchera pas.

1voto

James Thompson Points 15464

En général, conserver des données de ce type n'est pas une bonne chose à faire si vous pouvez l'éviter, car les gens confondent toujours les tabulations et les espaces.

La résolution de votre problème est très simple dans un langage de script comme Perl, Python ou Ruby. Voici quelques exemples de code :

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

1voto

Michiel Buddingh Points 3437

Le faire passer par quelque chose comme awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }' . Cela transformera les espaces en tabulations.

0 votes

@MB : J'ai besoin de garder l'espace intact.

1 votes

Il existe sans aucun doute un moyen plus propre de le faire, mais rien ne vous empêche de le passer dans awk, de remplacer les espaces par des tabulations, de trier les données, puis de le repasser dans awk et de remplacer les tabulations par des espaces.

3 votes

Cela ne fonctionnera pas si vous souhaitez conserver un mélange de tabulations et d'espaces.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X