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 :

Fonction découpage en shell (awk sed split ?)


Sujet :

Shell et commandes GNU

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Février 2015
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2015
    Messages : 25
    Points : 6
    Points
    6
    Par défaut Fonction découpage en shell (awk sed split ?)
    Bonjour,

    pourriez vous m'apporter votre aide pour écrire cette fonction dans un script bash/shell:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chainecomplete="var_1,var_2,var_3,var_n,..."  #(le nombre d’occurrence étant variable)
    Pour chaque variable séparée par un séparateur "virgule" et pouvant se répéter ou pas plusieurs fois, je dois faire un echo var_n de cette variable.

    Après plusieurs tentatives, je ne sais pas comment écrire cette fonction (awk ?).

    Merci beaucoup !

    Breizho

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    Bonjour,

    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IFS=',' read -a array <<<"$taChaine"
    printf '%s\n' "${array[@]}"
    tu as une solution, maintenant explique la solution.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    old="$IFS"; IFS=","; for x in $chainecomplete; do echo "[$x]"; done; IFS="$old"
    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]

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

    Ou encore (en bash) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf "${chainecomplete//,/\\n}\n"
    Cordialement.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    La solution boeuf (si tu ne veux pas utiliser IFS):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "${chainecomplete}" | tr ',' '\n'
    et, si tu veux faire autre chose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    echo "${chainecomplete}" | tr ',' '\n' | while read var
    do
    echo "je fais ce que je veux avec ${var}"
    done
    Note que si ${chainecomplete} contient des espaces, tabulations ou returns, il ne faut PAS faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chainecomplete="var_1,var_2	environ ou guère plus,var_3,var_n,..."
    for var in $(echo "${chainecomplete}" | tr ',' '\n'); do echo "${var}"; done # PAS BON!

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    et, si tu veux faire autre chose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    echo "${chainecomplete}" | tr ',' '\n' | while read var
    do
    echo "je fais ce que je veux avec ${var}"
    done
    C'est un bon outil... excepté sur un détail: toute variable remplie dans le pipe est perdue en fin de pipe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    i=0
    echo "${chainecomplete}" | tr ',' '\n' | while read var
        do
        echo "je fais ce que je veux avec ${var} mais je compte mes itérations"
        i=$(($i + 1))
    done
    # Combien en ai-je ???
    echo $i    # Surprise, i=0 !!!
    On peut passer outre si on a simplement besoin d'afficher le résultat juste après en utilisant les parenthèses groupement de processus...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    i=0
    echo "${chainecomplete}" | tr ',' '\n' | (
        while read var
            do
            echo "je fais ce que je veux avec ${var} mais je compte mes itérations"
            i=$(($i + 1))
        done
        # Combien en ai-je ???
        echo $i    # Là ok, on a la bonne valeur
    )
    Mais ça devient difficile si on doit réutiliser la valeur bien plus tard. Mais bon, si on n'a pas besoin de mémoriser quelque chose durant l'itération pour s'en servir plus tard, c'est alors une bonne méthode.

    Petit détail: ce souci n'apparait pas en ksh (jamais compris pourquoi...)
    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]

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    ce souci n'apparait pas en ksh (jamais compris pourquoi...)
    et c'est configurable en bash, dans un script (parce que le contrôle des tâches n'est pas activé), avec la shell option lastpipe.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    On peut passer outre si on a simplement besoin d'afficher le résultat juste après en utilisant les parenthèses groupement de processus...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    i=0
    echo "${chainecomplete}" | tr ',' '\n' | (
        while read var
            do
            echo "je fais ce que je veux avec ${var} mais je compte mes itérations"
            i=$(($i + 1))
        done
        # Combien en ai-je ???
        echo $i    # Là ok, on a la bonne valeur
    )
    Oui, et on peut même créer un process de moins en remplaçant les parenthèses par des accolades

    Mais ça devient difficile si on doit réutiliser la valeur bien plus tard. Mais bon, si on n'a pas besoin de mémoriser quelque chose durant l'itération pour s'en servir plus tard, c'est alors une bonne méthode.
    Outre la solution shop lastpipe proposée par N_BaH, on peut stocker UNE valeur (à condition de ne pas trop écrire sur la stdout ):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    i=0
    i=$(echo "${chainecomplete}" | tr ',' '\n' | {
        while read var
            do
            echo "je fais (presque) ce que je veux avec ${var} mais je compte mes itérations" 1>&2
            i=$(($i + 1))
        done
        # Combien en ai-je ???
        echo -n $i    # Là ok, on a la bonne valeur
    })
    echo $i    # Et ici aussi!
    On peut aussi utiliser la substitution de process (est-ce bien le terme officiel?):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    i=0
    while read var
        do
        echo "je fais ce que je veux avec ${var} mais je compte mes itérations"
        i=$(($i + 1))
    done < <(echo "${chainecomplete}" | tr ',' '\n')
    # Combien en ai-je ???
    echo $i    # Surprise, i=5 !!!
    Petit détail: ce souci n'apparait pas en ksh (jamais compris pourquoi...)
    cf. http://mywiki.wooledge.org/BashFAQ/024

  9. #9
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 278
    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 278
    Points : 12 726
    Points
    12 726
    Par défaut
    Voici une forme qui évite le sous-shell pour la boucle while:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    chainecomplete="var_1,var_2,var_3,var_4,xx yy,var_5"
    while read var
    do
     echo "la valeur est:$var"
    done<<EOF
    $(echo "${chainecomplete}" | tr ',' '\n')
    EOF
    Cordialement.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    ah que c'est moche.
    :/

    je crois que je préfère risquer de perdre une accolade, et relire tout mon script (correctement indenté ça ne devrait pas être un problème).
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 278
    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 278
    Points : 12 726
    Points
    12 726
    Par défaut
    J'ai jamais dit que c'était beau, c'est juste pour dire qu'il y a moyen de le faire pour que cela fonctionne au moins en bash, ksh et dash.
    Cordialement.

Discussions similaires

  1. Réponses: 13
    Dernier message: 27/05/2015, 20h51
  2. Réponses: 0
    Dernier message: 05/06/2014, 12h03
  3. Regexp shell pour sed
    Par GLDavid dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 15/11/2006, 16h21
  4. Réponses: 6
    Dernier message: 08/06/2006, 10h07
  5. Réponses: 10
    Dernier message: 17/12/2003, 13h51

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