194 votes

Comment utiliser l'opérateur mod en bash ?

J'essaie une ligne comme celle-ci :

for i in {1..600}; do wget http://example.com/search/link $i % 5; done;

Ce que j'essaie d'obtenir comme résultat est :

wget http://example.com/search/link0
wget http://example.com/search/link1
wget http://example.com/search/link2
wget http://example.com/search/link3
wget http://example.com/search/link4
wget http://example.com/search/link0

Mais ce que j'obtiens en fait est juste :

    wget http://example.com/search/link

0voto

Gabriel Staples Points 1804

Comment utiliser tous les opérateurs de bash, et l'expansion arithmétique, en bash

Sur les 346 000 visiteurs qui ont répondu à cette question jusqu'à présent, je suis prêt à parier que 344,9 000 d'entre eux souhaitent simplement obtenir une réponse au titre de la question :

Comment utiliser l'opérateur mod en bash ?

J'ai même cherché sur Google "bash modulus" à la recherche de cette réponse, et j'ai atterri ici. Donc, maintenant que j'ai compris, allons directement à l'essentiel :

Comment utiliser le module ( % ) en bash

Faites ceci, par exemple :

# 7 mod 4 (answer is 3, but to print the output you must use one of the cmds
# below)
$((7 % 4))

# [PREFERRED: no quotes]
# print the result (double quotes are not required)
echo $((7 % 4))

# print the result (with double quotes if you like)
echo "$((7 % 4))"

Exemple avec des variables :

num1="7"
num2="4"

# [PREFERRED: no $ signs nor extraneous quotes] result is 3
echo $((num1 % num2))

# Also ok: with $ signs
echo $(($num1 % $num2))

# Also ok: with $ signs and extra quotes
echo "$(("$num1" % "$num2"))"

Stockez le résultat dans une variable :

mod=$((num1 % num2))
echo "$mod"  # result is 3

El principaux liens à étudier pour ces concepts sont ceux-ci, de la Manuel officiel de l'utilisateur de GNU bash :

  1. Expansion arithmétique de Bash
  2. Arithmétique du shell Bash

Plus d'informations sur "l'expansion arithmétique" de bash

J'ai appris ce qui précède de La réponse de @Mark Longair (bien que cela m'ait demandé un certain effort pour tout comprendre), et c'est là que j'ai trouvé le lien ci-dessous. J'ai ensuite fait d'autres recherches.

El $(( )) est appelée "Expansion arithmétique", et est décrite dans la version officielle de GNU bash manuel d'utilisation ici : https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Arithmetic-Expansion .

Exemples de base (lieu echo devant chacun d'eux pour voir le résultat s'imprimer à l'écran) :

# general form
$((mathematical_expression))

# addition
$((7 + 4))  # 11

# subtraction
$((7 - 4))  # 3

# modulus (remainder)
$((7 % 4))  # 3

# logical AND
$((7 && 4))  # 1

# bitwise AND
$((7 & 4))  # 4

# etc.
# See the full operator list below for more

Les guillemets autour de l expansion arithmétique ne sont pas nécessaires. Extrait du manuel ci-dessus (c'est nous qui soulignons) :

L'expression est traitée comme si elle était entre guillemets. mais un guillemet double à l'intérieur des parenthèses n'est pas traité spécialement. Tous les tokens de l'expression subissent l'expansion des paramètres et des variables, la substitution des commandes et la suppression des guillemets. Le résultat est traité comme l'expression arithmétique à évaluer. Les expansions arithmétiques peuvent être imbriquées.

Pour tous opérateurs arithmétiques shell , voir le "Arithmétique de la coquille" de la section du manuel GNU bash ici : https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Arithmetic

Vous avez essentiellement tous les opérateurs mathématiques du langage C à votre disposition. L'arithmétique est effectuée "dans des nombres entiers de largeur fixe sans contrôle de débordement", donc si vous faites echo $((11/10)) o echo $((19/10)) vous obtiendrez 1 dans les deux cas puisque la partie fractionnaire est tronquée pour les entiers.

Extrait du lien du manuel juste au-dessus (c'est nous qui soulignons) :

L'évaluation se fait dans des entiers de largeur fixe sans vérification du débordement, bien que la division par 0 soit piégée et signalée comme une erreur. Les opérateurs, leur précédence, leur associativité et leurs valeurs sont les mêmes que dans le langage C. .

Puisque les opérateurs arithmétiques dans bash ont la même précédence qu'en C, comme il est indiqué ci-dessus, vous pouvez également vous référer à la précédence des opérateurs C du wiki de la communauté cppreference ici : https://en.cppreference.com/w/c/language/operator_precedence <-- mettez ça dans votre sac à outils.

Arithmétique Shell : voici tous les opérateurs supportés du manuel GNU Bash

Ils sont énumérés dans l'ordre de la plus haute à la plus basse priorité :

  1. id++ id--
    1. variable post-incrément et post-décrément
  2. ++id --id
    1. Pré-incrémentation et pré-décrémentation des variables
  3. - +
    1. unaire moins et plus
  4. ! ~
    1. négation logique et par bit
  5. **
    1. exponentiation
  6. * / %
    1. multiplication, division, reste
  7. + -
    1. addition, soustraction
  8. << >>
    1. décalage des bits à gauche et à droite
  9. <= >= < >
    1. comparaison
  10. == !=
    1. égalité et inégalité
  11. &
    1. AND par bit
  12. ^
    1. OU exclusif par bit
  13. |
    1. OU par bit
  14. &&
    1. ET logique
  15. ||
    1. OU logique
  16. expr ? expr : expr
    1. opérateur conditionnel
  17. = *= /= %= += -= <<= >>= &= ^= |=
    1. affectation
  18. expr1 , expr2
    1. virgule

Utilisation de bases alternatives dans votre arithmétique, comme le binaire (base 2), l'octal (base 8) et l'hexa (base 16).

Pour en savoir plus sur l'utilisation de différentes bases, telles que la base 2 (binaire), la base 8 (octal) ou la base 16 (hex) avec les opérateurs arithmétiques de bash, lisez les deux paragraphes suivants la liste "Arithmétique Shell" ci-dessus dans le manuel .

Voici quelques exemples rapides avec saisir des nombres décimaux (base 10), octaux (base 8), hexagonaux (base 16) et binaires (base 2). utilisés dans les calculs :

# hex 0xa (decimal 10) + decimal 5 = decimal 15
echo $((0xa + 5))  # prints `15` (decimal 15)
# OR (same thing)
echo $((16#a + 5))  # prints `15` (decimal 15)

# octal 071 (decimal 57) + hex 0xaa (decimal 170) = decimal 227
echo $((071 + 0xaa))  # prints `227` (decimal 227)
# OR (same thing)
echo $((8#71 + 16#aa))  # prints `227` (decimal 227)

# binary 1011 (decimal 11) + decimal 2 = decimal 13
echo $((2#1011 + 2))  # prints `13` (decimal 13)

# binary 1111 (decimal 15) + binary 11111 (decimal 31) = decimal 46
echo $((2#1111 + 2#11111))  # prints `46` (decimal 46)

A imprimer en tant que hex utiliser printf "0x%X \n " numéro :

# prints `0x2E` (hex 2E, or decimal 46)
printf "0x%X\n" $((2#1111 + 2#11111))

A imprimer en tant que binaire utiliser bc (voir ma réponse ici ) :

# prints `0b101110` (decimal 46)
printf "0b%s\n" "$(echo "obase=2; $((2#1111 + 2#11111))" | bc)"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X