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 :

Split d'un fichier


Sujet :

Shell et commandes GNU

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Avril 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Avril 2013
    Messages : 3
    Par défaut Split d'un fichier
    Bonjour le Forum,

    Débutant en bash, je souhaiterai optimiser mon premier script.

    Lecture d'un fichier avec split sur ";".

    Version 1.0
    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
     
    while read line
    do
       N_ENV=$(echo "$line" | cut -d';' -f1)
       N_APP=$(echo "$line" | cut -d';' -f2)
       N_JOB=$(echo "$line" | cut -d';' -f3)
       V_COM=$(echo "$line" | cut -d';' -f4)
     
       # Application du changement
    #  ${PATHVTOM}/vtaddjob /Nom="${N_ENV}/${N_APP}/${N_JOB}" /Comm="${V_COM}"
       if [ $? -eq 0 ] ; then
          echo -e "[${VERT}OK${NORMAL}] `date +"%D %H:%M"` # $i \t ENV=${N_ENV} APP=${N_APP} JOB=${N_JOB} \t COM=${V_COM}"
       else
          echo -e " [${ROUGE}KO${NORMAL}]"
          exit 2
       fi
     
    done < ${FILE_INPUT}
    Ce script est fonctionnel, mais ayant lu que l'utilisation d'une boucle "while" était déconseillée, j'essaie d'extraire mes champs de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for item in $(cut -d";" -f1,4 $FILE_INPUT)
    do
      echo $item
    done
    La variable item me renvoie la ligne complète.

    Question: comment lire f1, f2, f3 et f4 ?

    Merci par avance de vos suggestions.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut
    Bonjour,

    l'utilisation d'une boucle "while" était déconseillée,
    où ça ?
    qui ça ?
    dans quel contexte ?

    une boucle while est tout à fait indiquée ici.

    voir Comment parser un fichier.

    par contre, il est fortement déconseillé d'utiliser une boucle for pour parcourir la sortie d'une substitution de commandes !
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Lecture d'un fichier avec split sur ";".
    Mon premier reflexe est de répondre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ cat initial.txt 
    toto;tata;tsoin;
    et;pareil;ici
    presque
    $ grep -o '[^;]*' initial.txt 
    toto
    tata
    tsoin
    et
    pareil
    ici
    presque
    $
    Sinon, si tu as un fichier bien organisé (genre fichier csv) tu as intérêt à utiliser awk.
    Mais on comprend pas trop le but pour l'instant. La balle est dans ton camp

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Avril 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Avril 2013
    Messages : 3
    Par défaut Utilisation de For au lieu de While
    Bonjour N_BaH et Flodelarab,

    Merci de vos réponses.

    Dans le tutoriel "http://eric-sanchis.developpez.com/linux/shell/bash/", celui-ci précise
    La lecture ligne par ligne d’un fichier à l’aide d’une commande interne
    while est lente et peu élégante. Il est préférable d’utiliser une suite de filtres permettant d’aboutir au résultat voulu.
    Par exemple, en utilisant un filtre supplémentaire (la commande unix cut), on peut s’affranchir de l’itération while dans le programme
    Je souhaite simplifier les 4 exécutions de la fonction cut.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       N_ENV=$(echo "$line" | cut -d';' -f1)
       N_APP=$(echo "$line" | cut -d';' -f2)
       N_JOB=$(echo "$line" | cut -d';' -f3)
       V_COM=$(echo "$line" | cut -d';' -f4)
     
       # Application du changement
    #  ${PATHVTOM}/vtaddjob /Nom="${N_ENV}/${N_APP}/${N_JOB}" /Comm="${V_COM}"
    Merci pour le lien "Comment parser un fichier".

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jean-marc69 Voir le message
    Bonjour N_BaH et Flodelarab,

    Merci de vos réponses.

    Dans le tutoriel "http://eric-sanchis.developpez.com/linux/shell/bash/", celui-ci précise
    La lecture ligne par ligne d’un fichier à l’aide d’une commande interne
    while est lente et peu élégante. Il est préférable d’utiliser une suite de filtres permettant d’aboutir au résultat voulu.
    Par exemple, en utilisant un filtre supplémentaire (la commande unix cut), on peut s’affranchir de l’itération while dans le programme
    Salut
    C'est vrai que si on peut obtenir directement le résultat voulu par le biais d'une commande spécifique sans avoir à traiter le fichier ligne par ligne, c'est mieux. Bien évidemment quelque part dans la chaine il y a fatalement un traitement ligne à ligne mais si c'est la commande (compilée) qui le fait, ce sera fait bien plus rapidement qu'en shell.

    Mais si on peut pas utiliser cet avantage, alors le cat fichier |while read ligne redevient nécessaire et reste préférable à un for ligne in $(cat fichier)...

    Citation Envoyé par jean-marc69 Voir le message
    Je souhaite simplifier les 4 exécutions de la fonction cut.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
       N_ENV=$(echo "$line" | cut -d';' -f1)
       N_APP=$(echo "$line" | cut -d';' -f2)
       N_JOB=$(echo "$line" | cut -d';' -f3)
       V_COM=$(echo "$line" | cut -d';' -f4)
     
       # Application du changement
    #  ${PATHVTOM}/vtaddjob /Nom="${N_ENV}/${N_APP}/${N_JOB}" /Comm="${V_COM}"
    Pour moi cette solution reste la meilleure (le cut est un des programmes de traitement de flux les plus rapides qui soient). Et le quadruple appel reste obligé puisque tu veux récupérer 4 éléments différents.
    Mais si vraiment tu veux éviter de faire appel à un programme externe, tu peux y arriver en ne passant que par des outils internes shell de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    old="$IFS"; IFS=";"; set $line; IFS="$old"; unset old
    # Je mets tout sur une seule ligne pour qu'on comprenne bien que ces 4 commandes sont liées
     
    # Application du changement
    $PATHVTOM/vtaddjob /Nom="$1/$2/$3" /Comm="$4"
    Moi personnellement j'aime pas (en plus de toucher à l'IFS ce qui est méga dangereux, on perd les arguments précédents) mais bon, je ne suis pas un intégriste (comme certains modos avec le ls... suivez mon regard )

    PS: évite les accolades systématiques aux noms de variables. Ca n'a que peu d'utilité et ça alourdit l'écriture (et la lecture)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Avril 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Avril 2013
    Messages : 3
    Par défaut
    Merci Sve@r de ces précieux conseils.

  7. #7
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 347
    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 347
    Par défaut
    Bonjour,
    Un peut moins portable, mais si c'est du bash (pas trop vieux tout de même )
    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
    $ echo $N_APP
     
    $ echo $N_ENV
     
    $ echo $N_JOB
     
    $ echo $V_COM
     
    $ read N_ENV N_APP N_JOB V_COM <<<$(echo "titi;toto;tata;tutu" | cut  --output-delimiter=' ' -d';' -f1-4)
    $ echo $N_APP
    toto
    $ echo $N_ENV
    titi
    $ echo $N_JOB
    tata
    $ echo $V_COM
    tutu

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read N_ENV N_APP N_JOB V_COM < <( cut  --output-delimiter=' ' -d';' -f1-4 <<<"titi;toto;tata;tutu")

    voire avec un tableau si le nom des variables n'est pas indispensable.

    mais bon, tant qu'on ne verra pas de quoi a l'air le fichier...
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 347
    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 347
    Par défaut
    Génial

    En me foulant un peu, j'aurai pu effectivement me passer du echo, par contre je ne connaissais pas du tout cette syntaxe de "< <(....)".
    Il y a de la documentation la dessus ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

Discussions similaires

  1. [Batch] Split d'un fichier de donnée en sous-fichiers
    Par SnOwMaNz dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 15/04/2010, 23h08
  2. Split complexe sur fichier texte
    Par Mocodo dans le forum VBScript
    Réponses: 1
    Dernier message: 31/03/2010, 13h28
  3. [PHP 5.0] split d'un fichier txt
    Par kOrt3x dans le forum Langage
    Réponses: 4
    Dernier message: 17/11/2009, 17h58
  4. Split d'un fichier pdf
    Par nature dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 19/07/2006, 08h15
  5. Split d'un fichier entre 2 patterns
    Par mirascheat dans le forum Langage
    Réponses: 7
    Dernier message: 17/10/2005, 17h58

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