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

Linux Discussion :

Faire la somme de 2 listes en shell


Sujet :

Linux

  1. #1
    Membre du Club
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Points : 57
    Points
    57
    Par défaut Faire la somme de 2 listes en shell
    Bonjour,

    voila je souhaiterais savoir comment faire la somme de 2 listes ?

    Par exemple ce script qui prend en argument des éléments pour faire une liste :

    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/bash
    j=`echo $#`
    k=0
    while [ $k -lt $j ]
    do
    for i in `echo $@`
    do
    tub[$k]=$i
    k=`expr $k + 1`
    done
    done
    echo ${tub[*]}
    echo ${#tub[*]}
     
    [root@DELTA /]# ./table 1 2 5 k lo p
    1 2 5 k lo p
    6
    Mon but serait de créer 2 listes et d'en faire la somme dans une 3 eme liste, j'ai essayé de trouver une façon de le faire, mais je rentre dans de multiple boucles, variable etc.. et cela n'optimise pas tellement le code, donc si vous avez une idée de comment faire plus simple je suis perneur, merci d'avance.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Code ./liste : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/bin/bash
     
    maListe=( "$@" )
    echo "${maListe[@]}"
    echo ${#maListe[@]}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ./liste 1 2 5 "k a" lo p
    1 2 5 k a lo p
    6
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre du Club
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Points : 57
    Points
    57
    Par défaut
    Oh désolé, j'ai pas été très claire

    En faite le but est de disposer de deux listes avec des chiffres :

    list1 = 1, 2, 3, 4,5
    list2 = 6, 7, 8, 9, 10

    et d'avoir une 3ème liste avec comme éléments les résultats des sommes des 2 premières listes :

    list3 =7,9,11,13,15

    Voilà merci pour votre retour

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    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/bash
     
    list1=( 1 2 3 4 5 )
    list2=( 6 7 8 9 10 11)
     
    test() {
       var="${@}"
       myArr1=( ${var%%,*} )
       myArr2=( ${var##*,} )
       for (( x=0; x<${#myArr1[@]}; x++ ))
       do echo $(( ${myArr1[x]} + ${myArr2[x]:-0} ))
       done
    }
     
    if (( ${#list1[@]} >= ${#list2[@]} ))
    then list3=( $(test "${list1[@]}","${list2[@]}") )
    else list3=( $(test "${list2[@]}","${list1[@]}") )
    fi
    echo ${list3[@]}
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre du Club
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Points : 57
    Points
    57
    Par défaut
    Bonjour,


    merci pour la réponse, et en effet ça marche, mais pourrais-tu m'éclairer sur cette partie du code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    test() {
       var="${@}"
       myArr1=( ${var%%,*} )
       myArr2=( ${var##*,} )
       for (( x=0; x<${#myArr1[@]}; x++ ))
       do echo $(( ${myArr1[x]} + ${myArr2[x]:-0} ))
       done
    Que fait le test exactement ? ces deux variables agissent comment sur les listes ? :

    myArr1=( ${var%%,*} )
    myArr2=( ${var##*,} )

    Enfin, sur cette partie :

    do echo $(( ${myArr1[x]} + ${myArr2[x]:-0} ))

    que signifie ":-0}" ?

    Merci pour tes réponses.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    -
    myArr1=( ${var%%,*} )
    j'alimente un tableau/liste avec le contenu de $var, jusqu'au séparateur arbitraire `,'
    myArr2=( ${var##*,} )
    pareil à partir du séparateur arbitraire
    ${myArr2[x]:-0}
    si il n'y a plus d'élément dans le tableau/liste, alors utiliser zéro

    regarde la partie sur la substitution des paramètres dans le man de bash

    -
    l'utilisation d'une boucle for dans le style C, oblige à itérer sur le tableau comprenant le nombre d'éléments le plus important
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre du Club
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Points : 57
    Points
    57
    Par défaut
    Merci pour ces précisions

    Je savais pas que l'on pouvait utiliser des boucle C dans du shell, ça ouvre pas mal de possibilités.

    Merci encore !

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sedawk Voir le message
    Merci pour ces précisions

    Je savais pas que l'on pouvait utiliser des boucle C dans du shell, ça ouvre pas mal de possibilités.

    Merci encore !
    Non.

    Ce ne sont pas des boucles C dans du shell. Ce sont des boucles shell tout court. Et encore, uniquement en bash (et shells plus évolués) car en Bourne Shell ben il faut passer par du while test.

    Toutefois, par souci d'homogénéisation, la syntaxe de cette évolution bash par rapport à sh a été adaptée à partir de celle du C...
    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]

  9. #9
    Membre du Club
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Points : 57
    Points
    57
    Par défaut
    Vous savez comment faire cette somme sans la boucle for style C ? Je ne voit pas comment on peut faire avec un while test ?

    Pour la portabilité je ne suis pas sur que le for style C fonctionne partout.

    Une dernière question, admettons que l'on veuille soustraire ces listes au lieu de les aditionner et que l'on ne veut que des résultats nuls ou positifs, il faudrait donc trier ces listes afin de faire des opérations qui ne renvoient pas de résultats négatifs, comment procèderiez-vous ?

    Exemple : liste1 (1 9 6 7) - liste2 (5 4 8 2) => liste3 (-4 5 -2 5) [résultat que l'on ne veut pas]

    Le but étant d'identifier les opérations qui renverraient négatif et de changer l'ordre des chiffres donnant ces résultats.

    merci.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    hmm

    si le shell ne supporte pas les boucles for arithmétiques ( for (( ... )); do ...; done), peut-être ne supportera-t-il pas les tableaux/listes, non plus ?
    éventuellement :
    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
    #!/bin/sh
     
    list1=( 1 9 6 7 )
    list2=( 5 4 8 2 )
    test() {
       var="${@}"
       myArr1=( ${var%%,*} )
       myArr2=( ${var##*,} )
    x=0
    while [ $x -lt ${#myArr1[@]} ]
    do tmp=$(( ${myArr1[x]} - ${myArr2[x]:-0} ))
       if [ $tmp -gt 0 ]
       then echo $tmp
       fi
       x=$(($x+1))
    done
    }
     
    if (( ${#list1[@]} >= ${#list2[@]} ))
    then list3=( $(test "${list1[@]}","${list2[@]}") )
    else list3=( $(test "${list2[@]}","${list1[@]}") )
    fi
    echo "${list3[@]}"
    dans
    if [ $tmp -gt 0 ]
    je ne met pas de guillemets, car il s'agit de nombres qui ne peuvent pas contenir d'espaces.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sedawk Voir le message
    Exemple : liste1 (1 9 6 7) - liste2 (5 4 8 2) => liste3 (-4 5 -2 5) [résultat que l'on ne veut pas]

    Le but étant d'identifier les opérations qui renverraient négatif et de changer l'ordre des chiffres donnant ces résultats.
    Même en mettant liste 1 et liste 2 dans l'ordre croissant, ça donnera toujours (1, 6, 7, 9) - (2, 4, 5, 8) et ça fera toujours -1; 2; 2; 1 soit un résultat non désiré...
    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]

  12. #12
    Membre du Club
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Points : 57
    Points
    57
    Par défaut
    Merci N_Bah pour la petite correction, je pense que pour la portabilité, les tableaux ne devraient pas poser de soucis

    @Sve@r, et justement n'y-a-t-il pas moyen de faire en sorte de détecter une opération dont le résultat serait négatif et d'inverser les chiffres de tel sorte que cela puisse donner le résultat voulu ?

    Par exemple : (1, 6, 7, 9) - (2, 4, 5, 8)
    cela donnerait (2, 6, 7, 9) - (1, 4, 5, 8) => 1, 2, 2, 1

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    n'y-a-t-il pas moyen de faire en sorte de détecter une opération dont le résultat serait négatif et d'inverser les chiffres de tel sorte que cela puisse donner le résultat voulu ?

    Par exemple : (1, 6, 7, 9) - (2, 4, 5, 8)
    cela donnerait (2, 6, 7, 9) - (1, 4, 5, 8) => 1, 2, 2, 1
    trop compliqué, sans machine à remonter dans le temps

    en ayant défini, au début du script, une fonction abs, telle que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    abs() { echo $(( $1 < 0 ? -$1 : $1 )); }
    plutôt que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       tmp=$(( ${myArr1[x]} - ${myArr2[x]:-0} ))
       if [ $tmp -gt 0 ]
       then echo $tmp
       fi
    écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    abs $(( ${myArr1[x]} - ${myArr2[x]:-0} ))
    si j'ai bien compris, ce que tu veux.

    Tu sais déjà sur quels shells sera utilisé ton script ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sedawk Voir le message
    @Sve@r, et justement n'y-a-t-il pas moyen de faire en sorte de détecter une opération dont le résultat serait négatif et d'inverser les chiffres de tel sorte que cela puisse donner le résultat voulu ?

    Par exemple : (1, 6, 7, 9) - (2, 4, 5, 8)
    cela donnerait (2, 6, 7, 9) - (1, 4, 5, 8) => 1, 2, 2, 1
    Ah ok. en fait tu ne fais pas que changer le sens des chiffres de la liste, tu vas carrément jusqu'à permuter des chiffres d'une liste dans l'autre pour ne pas avoir de négatif.

    Ben N_BaH m'a devancé. Le plus simple en effet c'est que tu mettes chaque liste dans l'ordre croissant => (1, 6, 7, 9) - (2, 4, 5, 8) puis tu calcules la valeur absolue de la soustraction => 1, 2, 2, 1

    Citation Envoyé par N_BaH Voir le message
    en ayant défini, au début du script, une fonction abs, telle que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    abs() { echo $(( $1 < 0 ? -$1 : $1 )); }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    abs() { echo $1 |sed -e "s/^-{1,}//"; }
    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]

Discussions similaires

  1. [AC-2003] Faire la somme des valeurs contenus dans plusieurs listes déroulantes
    Par kavuza dans le forum VBA Access
    Réponses: 3
    Dernier message: 08/08/2012, 10h21
  2. Réponses: 9
    Dernier message: 25/01/2012, 17h07
  3. [SP-2010] Faire une somme sur une colonne d'une liste
    Par sebfreu dans le forum SharePoint
    Réponses: 6
    Dernier message: 19/01/2012, 11h05
  4. Réponses: 15
    Dernier message: 21/05/2010, 00h36
  5. Réponses: 1
    Dernier message: 23/01/2007, 18h23

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