Forum Programmation.shell Comparaison de deux entiers sous bash

Posté par  .
Étiquettes : aucune
0
8
mai
2009
Bonjour,

Sous bash, a-t-on vraiment besoin d'écrire tout ça pour comparer deux réels ?


#!/bin/bash
if [ `echo $1 | grep "-"` ] && [ `echo $2 | grep -v "-"` ]; then
echo "$1 < $2"
elif [ `echo $2 | grep "-"` ] && [ `echo $1 | grep -v "-"` ]; then
echo "$1 > $2"
else
NumberOne=`echo $1 | tr -d . | tr -d -`
NumberTwo=`echo $2 | tr -d . | tr -d -`
StringNumberDifference=$((${#NumberOne}-${#NumberTwo}))
if (( ${#NumberOne} >= ${#NumberTwo} )); then
GreaterStringNumber=${#NumberOne}
for ((i=0 ; ${StringNumberDifference#-} - $i ; i++))
do
NumberTwo=$NumberTwo$"0"
done
else
GreaterStringNumber=${#NumberTwo}
for ((i=0 ; ${StringNumberDifference#-} - $i ; i++))
do
NumberOne=$NumberOne$"0"
done
fi
for ((i=0 ; $GreaterStringNumber - $i ; i++))
do
if (( `echo ${NumberOne:$i:1}` > `echo ${NumberTwo:$i:1}` )) && [ `echo $1 | grep -v "-"` ]; then
echo "$1 > $2"
break
elif (( `echo ${NumberOne:$i:1}` > `echo ${NumberTwo:$i:1}` )) && [ `echo $1 | grep "-"` ]; then
echo "$1 < $2"
break
elif (( `echo ${NumberOne:$i:1}` < `echo ${NumberTwo:$i:1}` )) && [ `echo $1 | grep -v "-"` ]; then
echo "$1 < $2"
break
elif (( `echo ${NumberOne:$i:1}` < `echo ${NumberTwo:$i:1}` )) && [ `echo $1 | grep "-"` ]; then
echo "$1 > $2"
break
elif (( `echo ${NumberOne:$i:1}` == `echo ${NumberTwo:$i:1}` )) && (( $((i+1)) ==GreaterStringNumber )); then
echo "$1 = $2"
fi
done
fi


Question subsidiaire : si je voulais comparer X variables (X étant au choix de l'utilisateur), toujours sous bash, comment modifier la fonction précédente ?
  • # Non c'est même con.

    Posté par  . Évalué à 4.

    typeset -i mavar

    sinon rtfm pour les -eq & co
    • [^] # Re: Non c'est même con.

      Posté par  . Évalué à 1.

      Bonjour et merci pour la réponse même si je ne l'ai pas comprise
      Les valeurs ne sont pas des entiers naturels (integers) mais des réels.
      Je ne vois pas pourquoi 'typeset' va me faciliter la vie. En outre, il est dit qu'elle est obsolète par rapport à 'declare'
      Je ne comprends pas le commentaire sur les opérations arithmétiques (elles sont correctes).
      Cette fonction sera insérée dans un script Bash et pas ksh.
      • [^] # Re: Non c'est pas si con.

        Posté par  . Évalué à 1.

        Bash ne gérant les décimaux, cela me parait correct.

        «Je ne comprends pas le commentaire sur les opérations évaluations arithmétiques (elles sont correctes).»
        Et oui, et non : cf. `help test`
        [ $varNum1 -eq $varNum2 ] && echo "$varNum1 est égal à $varNum2"etc...

        La forme `COMMAND` est obsolescente, il faudrait lui préférer la forme $(COMMAND)
        Les echo $var | COMMAND, c'est moche, je préfère COMMAND <<<$var
        Aussi, if (( `echo $var ==...
        if (( $var ==...
        enfin, je veux dire :
        if [ $var -eq...
        Et pour l'indentation : merci, c'est pas des plus lisible.

        Quant à savoir si on peut faire plus simple, et comment l'adapter pour qu'il fonctionne avec plus deux arguments ???
        • [^] # Re: Non c'est pas si con.

          Posté par  . Évalué à 1.

          Grand merci pour ces conseils.
          Ça ne répond pas directement au fond du problème mais ça me permet au moins de rigoriser mon code...
          Désolé pour l'indentation qui a sauté au travers des balises, je ne sais pourquoi.
          • [^] # Re: Non c'est pas si con.

            Posté par  (site web personnel) . Évalué à 1.

            Sinon il y a aussi la solution bc :

            echo "$1 > $2 " | bc -l

            affiche 0 ou 1 suivant les valeurs
            • [^] # Re: Non c'est pas si con.

              Posté par  . Évalué à 1.

              Effectivement, cela répond au problème quand on a que deux variables.

              Mais si on a un nombre de valeur à comparer non connue au départ, comment construire une fonction qui sache gérer la variation du nombre de paramètres qui lui est passé ?

              Ex. avec une fonction appelée NumbersComparison :

              NumbersComparison -2 5.2 6.98741 3 doit renvoyer 6.98741 > 5.2 > 3 > -2

              NumbersComparison -7 10.5 24.8745 doit renvoyer 24.8745 > 10.5 > -7
              • [^] # Re: Non c'est pas si con.

                Posté par  . Évalué à 2.

                pour les trucs que le shell ne sais pas faire (sans using a gaz), j'utilise un autre language de script, par exemple php... que tu peux lancer depuis ton script d'ailleurs...

                et pour le multi-variable : un tableau, un sort()... ca devrait être faisable (php).
                • [^] # Re: Non c'est pas si con.

                  Posté par  . Évalué à 2.

                  Comme il faut toujours aller au bout de ce qu'on a commencé :


                  #!/bin/bash
                  function TriCroissant {
                  i=0
                  while [ ! -z "$1" ]
                  do
                  MatriceBrute[$i]=$1
                  i=$((i+1))
                  shift
                  done
                  MatriceTrie=($(echo ${MatriceBrute[@]} | tr ' ' '\n' | sort -k1,1n | paste -s -d ' ' ))
                  ListeCroissante=${MatriceTrie[0]}
                  for ((j=1 ; $i - $j ; j++))
                  do
                  [ $(bc -l <<< "${MatriceTrie[$((j-1))]} == ${MatriceTrie[$j]}") -eq 1 ] && \
                  ListeCroissante=$ListeCroissante$" <= "${MatriceTrie[$j]} || \
                  ListeCroissante=$ListeCroissante$" < "${MatriceTrie[$j]}
                  done
                  echo $ListeCroissante
                  }



                  >TriCroissant -2.0 3.5 4.1 15.052556

                  -2.0 < 3.5 < 4.1 < 15.052556
              • [^] # ça s'appelle du tri...

                Posté par  . Évalué à 1.

                comparer plus d'un nombre avec un opérateur binaire est étrange.
                Donc ça s'appelle plutôt le tri d'une liste que de la comparaison et il vaut mieux utiliser un langage fait pour ça : Perl le ferait en une ligne.

                ps: ou php qui est amha honteusement pompé dessus };)
  • # Ah ouais !

    Posté par  . Évalué à 1.

    une toute petite remarque, pour signaler que l'affichage vertical de tableau est simplifié par l'usage de la commande printf.
    Donc au lieu de echo "${arr[@]}" | tr ' ' '\n'utiliserprintf '%s\n' "${arr[@]}"
  • # bof non pas trop :)

    Posté par  . Évalué à 2.

    une seule ligne :P
    > cat test.sh
    #!/bin/bash
    sed -r 's/ /\n/g' <<<$@ | sort -n | tr '\n' '<' '

    en gros une ligne

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.