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 :

Récupération de la valeur maximale dans un fichier


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 12
    Points : 11
    Points
    11
    Par défaut Récupération de la valeur maximale dans un fichier
    Bonsoir, j'ai un fichier xml qui contient plusieurs informations. Parmis ces informations, il a des balises de type <value>N</value> avec N un nombre aléatoire. Je souhaite parcourir le fichier et stocker uniquement la plus grande valeur de cette balise dans une variable i. voici mon script :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #!/bin/sh
     
    nbre=1
    > data
    while read line
    do
       echo $line >data
     
       var=$(grep -o '<value>[^<]*</value>' | sed -e 's/[^>]*>\([^<]*\).*$/\1/g')
       if [ ${var}> nbre ]
       then
            i=$var
    		echo ${i}
     
    	else
            echo $line	
       fi
     
    done <text.xml
    merci de votre aide !

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 596
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 596
    Points : 19 481
    Points
    19 481
    Par défaut
    les opérateurs arithmétiques sont :
    -lt
    -le
    -eq
    -ge
    -gt

    voir help test.

    hors contexte d'évaluation arithmétique ($(( )), > est une redirection.

  3. #3
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 311
    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 311
    Points : 12 830
    Points
    12 830
    Par défaut
    Bonjour,

    De plus, étant donné que tu initialises la variable nbre à 1 pour faire la comparaison et que cette variable ne change jamais, tu obtiendras toute les valeur > 1 et non pas la valeur la plus grande.

    Une autre remarque, la regex du sed est belle mais couplé avec le grep que tu fais, je la trouve trop complexe.

    Une solution possible pour avoir la plus grande valeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep -o '<value>[0-9]\+</value>' text.xml | sed 's/[^0-9]//g' | sort -nur | head -1
    exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ cat text.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
        <value>toto</value> <!-- ne pas prendre en compte -->
        <value>100</value>
        <node><value>25</value></node>
        <node><value>200</value></node>
    </root>
    <root4><value></value>blabla<value>45</value></root4>
    $ grep -o '<value>[0-9]\+</value>' text.xml | sed 's/[^0-9]//g' | sort -nur | head -1
    200
    $
    ici, je fais un sort numérique inversé et avec l'option unique pour réduire le buffer.

    Cordialement.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 740
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 740
    Points : 31 070
    Points
    31 070
    Billets dans le blog
    1
    Par défaut
    Salut
    Autre remarque sur l'algo: tu considère que "1" est une valeur suffisamment petite et que tu trouveras d'autres valeurs plus grandes dans ton fichier. C'est bien évidemment très probable. Mais il peut arriver quand-même que cela ne soit pas le cas ou alors ça t'impose d'avoir déjà une idée de la plage de valeurs possibles.

    Une méthode plus robuste aurait été de ne pas initialiser de variable et de tester ensuite "valeur > variable ou variable inexistante". A ce moment là tu positionnes la valeur dans la variable. Ainsi même sans connaitre la plage des valeurs de ton fichier tu es certain de récupérer la valeur maximale (ou minimale éventuellement)

    Concernant la syntaxe, tu as oublié un "$" devant nbre dans ta comparaison et tu mélanges les variables avec accolades {} avec des variables sans accolades (homogénéité = lecture plus aisée).

    Sinon je ne vois pas trop ce que data vient faire la dedans ni pourquoi tu commences par vider ce fichier à la première ligne alors qu'il est immédiatement vidé de nouveau puis rempli dès la seconde...

  5. #5
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 450
    Points
    19 450
    Par défaut
    Bonjour.

    Je vais répéter mon message habituel concernant le parsing de fichiers XML : pour le cas échéant c'est plutôt simple car tu ne regarde qu'un motif, mais dès lors que tu auras du parsing plus complexe à faire (extraction de plusieurs balises avec des chemins précis avec des attributs précis...) l'utilisation de commandes shell style grep avec regexp, sort, head vont très vite montrer leur limites.

    Dans ce cas il existe des solutions prévue pour le parsing xml : xmllint que je ne trouve pas très pratique personnellement ou des langages de shells scripts plus évolués comme Perl ou PHP par exemple qui proposent notamment de faire des requête Xpath (un moyen assez efficace pour faire du parsing en lecture).

    Exemple en PHP :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    idriss@ThinkPad-T420 ~ $ cat test.xml 
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
        <value>toto</value> <!-- ne pas prendre en compte -->
        <value>100</value>
        <node><value>25</value></node>
        <node><value>200</value></node>
    </root>
    idriss@ThinkPad-T420 ~ $ cat script.php 
    #!/usr/bin/php
    <?php
        if (!isset($argv[1]) || !is_file($argv[1])){
            echo "USAGE : ./script.php <fichier.xml>\n";
            exit (1);
        }
     
        $xml = simplexml_load_file($argv[1]);
        $array = $xml->xpath('//value');
     
        $max = false;
        foreach ($array as $item){
            if(preg_match("/^[0-9]+$/", $item) 
                && (!$max || (int) $item >= (int) $max)){
                $max = $item;
            }
        }
     
        echo $max . "\n";
    ?>
    idriss@ThinkPad-T420 ~ $ ./script.php
    USAGE : ./script.php <fichier.xml>
    idriss@ThinkPad-T420 ~ $ ./script.php test.xml
    200
    idriss@ThinkPad-T420 ~ $
    Bien entendu, ça sera très probablement plus couteux que le grep donc s'il ne s'agit que de récupérer le max ici, le grep reste une bonne solution.

    Cordialement,
    Idriss

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Merci beaucoup pour vos réponses !

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

Discussions similaires

  1. [XML] valeur maximale dans un fichier XML
    Par wehtam dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 02/09/2011, 17h15
  2. Trouver la valeur maximale dans une matrice
    Par VanessaDu67 dans le forum MATLAB
    Réponses: 3
    Dernier message: 06/06/2007, 11h23
  3. Réponses: 2
    Dernier message: 03/02/2007, 16h35
  4. Réponses: 3
    Dernier message: 29/05/2006, 18h04
  5. Réponses: 1
    Dernier message: 25/04/2006, 22h29

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