IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Shell Bash : sort (tri) Les options


Sujet :

Shell et commandes GNU

  1. #1
    Membre régulier Avatar de Liamm
    Femme Profil pro
    Enseignant
    Inscrit en
    Janvier 2019
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 160
    Points : 80
    Points
    80
    Par défaut Shell Bash : sort (tri) Les options
    Bonjour,

    Je m'adresse à vous après moultes recherches infructueuses.

    J'ai un fichier texte (.txt ou .csv) que je voudrais trier.

    La colonne par laquelle je veux trier contient des valeurs numériques.

    Seulement ces valeurs peuvent contenir un séparateur de milliers :"NO-BREAK SPACE"

    D'après la commande chardet3 mon fichier texte est encodé en utf-8 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ chardet3 f19041.csv
    f19041.csv: utf-8 with confidence 0.99
    Question : Quelle(s) option(s) apporter à sort, pour que le tri marche correctement ?

  2. #2
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 309
    Points : 12 817
    Points
    12 817
    Par défaut
    Pas aussi simple que ça, faudrait avoir un exemple de ton fichier csv car, pour faire le tri dans ce cas, il faut supprimer l'espace insécable, faire le tri, puis le remettre...

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ cat sample
    100*00
    100*0
    100
    101*0
    Sans la transformation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ sort -n sample
    100
    100*0
    100*00
    101*0
    Avec la transformation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ sed -e 's/[^0-9]//g' sample| sort -n | sed -e 's/[0-9]\{3\}/&\xc2\xa0/g;s/[^0-9]$//'
    100
    100*0
    101*0
    100*00
    Mais ici, dans l'exemple, on traite toute la ligne, pas uniquement un champs... d'où le besoin d'avoir un exemple de ton fichier csv et du champs à prendre en compte.

    PS: le '*' est le caractère insécable transformé par le site

  3. #3
    Membre régulier Avatar de Liamm
    Femme Profil pro
    Enseignant
    Inscrit en
    Janvier 2019
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 160
    Points : 80
    Points
    80
    Par défaut Exemple de fichier transmis avec commande tri utilisée
    ftest.txt


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat $1 | sort -r -n  -t ";" -k8 | cut -d ";" -f 1,6-8
    Le tri est sur la 8ième colonne.
    $1 représente mon fichier ftest.txt passé en argument.

  4. #4
    Membre éprouvé Avatar de balkany
    Homme Profil pro
    Touriste
    Inscrit en
    Juillet 2017
    Messages
    346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Touriste

    Informations forums :
    Inscription : Juillet 2017
    Messages : 346
    Points : 977
    Points
    977
    Par défaut
    Je passerais par awk, encadré par des rev pour remettre les séparateurs de milliers en bon ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F ';' -v OFS=';' '{gsub("\xc2\xa0","",$8); print}' "$1" | sort -rnt ";" -k8 | rev | awk -F ';' -v OFS=';' '{gsub("[0-9]{3}","&\xc2\xa0",$5); gsub("\xc2\xa0$","",$5); print}' | rev
    Ensuite, tu peux rajouter ton cut en bout de chaine, ou bien intégrer cette modif au second awk, en faisant attention à l'ordre des champs car on travaille alors à l'envers.

  5. #5
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 271
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 271
    Points : 13 536
    Points
    13 536
    Par défaut
    Bonjour

    Une idée avec gawk (GNU awk) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ awk -F';' '{c=$8;gsub(/[^0-9,]/,"",c);gsub(",",".",c);a[c]=$0;} END{n=asorti(a,b,"@ind_num_asc");for (i=1;i<=n;i++) print a[b[i]];}' ftest.txt
    E T;X0013420404;Vive;Ubuntu;100;4,120;4,350;412,00;-23,00;-5,29;0,42;
    N;FI0009000699;Vive;Ubuntu;111;4,610;4,982;511,65;-41,35;-7,48;0,53;
    2;Z0013341881;Vive;Ubuntu;260;3,870;6,339;1*006,20;-641,99;-38,95;1,04;
    C;H0000129585;Vive;Ubuntu;70;42,310;29,861;2*961,70;871,43;41,69;3,05;
    V;P0000124771;Vive;Ubuntu;159;23,190;17,306;3*687,21;935,57;34,00;3,80;
    On trie les indices par ordre croissant numérique.
    "b" est le tableau des indices triés.
    "a" est le tableau qui contient les lignes de ton fichier texte comme valeur, et, en indice, le 8ème champ transformé en nombre à virgule.

    La fonction asorti() existe pour gawk mais pas awk. Pour connaître ta version :

  6. #6
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 309
    Points : 12 817
    Points
    12 817
    Par défaut
    @Balkany: petit défaut d'affichage si plus de 2 chiffres après la virgule...

    @Flodelarab: avec ta solution, on peut perdre des lignes dans le cas où on a des lignes avec les mêmes valeurs sur le champs 8...

    Une solution, sans toucher au valeurs que l'on désire conserver:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gawk -F\; '{X=$8;gsub(/[^0-9,]/,"",X)}$0=X";"$0' $1 | sort -t \; -k1 -rn | cut -d \; -f2,7-9

  7. #7
    Membre régulier Avatar de Liamm
    Femme Profil pro
    Enseignant
    Inscrit en
    Janvier 2019
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 160
    Points : 80
    Points
    80
    Par défaut Tri avec espaces non sécabbe
    Merci à tous : disedorgue, balkany, Flodelarab

  8. #8
    Membre chevronné
    Avatar de emixam16
    Homme Profil pro
    Chercheur en sécurité
    Inscrit en
    Juin 2013
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Chercheur en sécurité

    Informations forums :
    Inscription : Juin 2013
    Messages : 335
    Points : 1 837
    Points
    1 837
    Par défaut
    Bonjour à tous,


    Pour répondre plus simplement à ton problème, tu peux juste supprimer le caractère qui te gène à l'aide de la commande tr tr -d " ".

    Ton tri devient alors *beaucoup* plus simple

    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ cat test.c | tr -d " " | sort -r -n  -t ";" -k8  | cut -d ";" -f 1,6-8
    t -d ";" -f 1,6-8
    V;23,190;17,306;3687,21
    C;42,310;29,861;2961,70
    2;3,870;6,339;1006,20
    N;4,610;4,982;511,65
    E T;4,120;4,350;412,00

  9. #9
    Membre régulier Avatar de Liamm
    Femme Profil pro
    Enseignant
    Inscrit en
    Janvier 2019
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 160
    Points : 80
    Points
    80
    Par défaut
    Merci on y est presque !
    hormis que l'espace non sécable est différent de l'espace (tr -d " ")

  10. #10
    Membre chevronné
    Avatar de emixam16
    Homme Profil pro
    Chercheur en sécurité
    Inscrit en
    Juin 2013
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Chercheur en sécurité

    Informations forums :
    Inscription : Juin 2013
    Messages : 335
    Points : 1 837
    Points
    1 837
    Par défaut
    Citation Envoyé par Liamm Voir le message
    Merci on y est presque !
    hormis que l'espace non sécable est différent de l'espace (tr -d " ")
    Ça tombe bien, j'ai mis l'espace insécable en argument de tr -d et pas l'espace classique.

    J'ai vérifié, ma commande fonctionne

  11. #11
    Membre régulier Avatar de Liamm
    Femme Profil pro
    Enseignant
    Inscrit en
    Janvier 2019
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 160
    Points : 80
    Points
    80
    Par défaut
    Oui je pense que Developpez.com l'a retraduit par un espace; car j'ai fait un copier-coller de ta commande et ça n'a pas marché.
    Par contre en faisant en $ man tr
    j'ai vu que l'on pouvait exprimer le caractère en octal en ajoutant \NNN
    tr -d \NNN
    Reste à trouver les bonnes valeurs de NNN, sachant qu'en hexadécimal il me semble que l'espace non sécable s'écrit : \xc2\xa0
    Je cherche
    Je vais faire la conversion . . .
    à la mano

  12. #12
    Membre régulier Avatar de Liamm
    Femme Profil pro
    Enseignant
    Inscrit en
    Janvier 2019
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 160
    Points : 80
    Points
    80
    Par défaut
    J'ai tapé un peu au hazard car je ne sais jamais s'il faut des guillemets ou non :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat $1 | tr -d "\302\240" | sort -r -n  -t ";" -k8 | cut -d ";" -f 1,6-8
    et ça marche !
    Merci à tous !

  13. #13
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 271
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 271
    Points : 13 536
    Points
    13 536
    Par défaut
    et ça marche !
    Mouai. Ça marche. Tu parles. Cette solution défigure les données. On te fournit plus haut une solution qui ne défigure rien, et on te retrouve, dans d'autres discussions, encore en train de galérer, alors que cette discussion suffit. Pourquoi ne pas nous croire ?

    Je reformule la solution : Il faut créer un champ vraiment numérique, dérivé du champ 8, tout en gardant la ligne entière en mémoire. Après, que ton tri se fasse par awk, sort, ou autre, n'a plus d'importance, car tu as un fichier exploitable. Donc tu tries, et tu supprimes le champ temporairement créé.

    En ce qui concerne la redéfinition de LC_NUMERIC, je crois que thousands_sep est en lecture seule. Si tu veux modifier thousands_sep, il doit falloir recompiler une locale à toi en C. Est-ce vraiment ce que tu souhaites faire ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. ls finder bash sort : tris différents des fichiers
    Par niroub dans le forum Shell et commandes GNU
    Réponses: 25
    Dernier message: 21/09/2018, 21h11
  2. Un nouveau shell combine Python et les propriétés de Bash
    Par Coriolan dans le forum Général Python
    Réponses: 10
    Dernier message: 14/06/2016, 13h30
  3. Shell Bash Supprimer un } à la fin sans toutes les supprimer
    Par gaaara dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 27/03/2014, 16h17
  4. Utiliser les commandes du shell bash
    Par man in the hill dans le forum Linux
    Réponses: 3
    Dernier message: 20/07/2006, 10h43
  5. Vous gerez comment les options d'un programme?
    Par n0n0 dans le forum C++Builder
    Réponses: 5
    Dernier message: 17/05/2002, 13h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo