L'ajout de 1 à une variable ne fonctionne pas comme prévu (arithmétique Bash)

16

Si j'écris ce qui suit dans un terminal bash:

A="0012"
B=$((A+1))
echo $B

J'en reçois 11, pas 13 comme je m'y attendais !!!!!

J'ai cherché sur Google et je ne peux pas l'expliquer du tout, ou trouver comment je peux augmenter le nombre. (Je veux en fait finir avec B = "0013" et incrémenter une fois à chaque fois que j'utilise ceci comme préfixe pour mes sauvegardes)

Robert3452
la source
2
Méfiez-vous des zéros non significatifs sur pratiquement toutes les langues provenant d'UNIX. Cela signifie normalement octal.
Joshua
Non, vous n'êtes pas, vous obtenez 1011 binaire
Ken Mollerup

Réponses:

28

C'est parce que les nombres commençant par 0sont traités comme Octal par bash, donc il fait un ajout Octal (Base 8). Pour obtenir un ajout décimal pour cette structure, vous devez définir explicitement la base ou ne pas utiliser 00complètement.

Pour Decimal, la base est 10, dénotée par 10#:

$ A="10#0012"
$ echo $((A+1))
13
heemayl
la source
5

Vous pouvez essayer cette commande pour obtenir la réponse:

A="0012"
echo $A + 1 | bc

Vous trouverez plus d'informations sur la bccommande ici .

bc page de manuel:

NAME
       bc - An arbitrary precision calculator language

SYNTAX
       bc [ -hlwsqv ] [long-options] [  file ... ]

DESCRIPTION
       bc is a language that supports arbitrary precision numbers with interactive execution of statements.  There are some similarities
       in the syntax to the C programming language.  A standard math library is available by command line  option.   If  requested,  the
       math  library is defined before processing any files.  bc starts by processing code from all the files listed on the command line
       in the order listed.  After all files have been processed, bc reads from the standard input.  All code is executed as it is read.
       (If a file contains a command to halt the processor, bc will never read from the standard input.)

       This  version of bc contains several extensions beyond traditional bc implementations and the POSIX draft standard.  Command line
       options can cause these extensions to print a warning or to be rejected.  This document describes the language accepted  by  this
       processor.  Extensions will be identified as such.
fouiner
la source
4
Au lieu d'utiliser echoet un canal, vous pouvez utiliser la syntaxe "ici chaîne" de Bash. L'effet est le même, mais à mon humble avis la "chaîne ici" est plus belle: bc <<< "$A + 1":-)
Byte Commander
Une introduction d'une ou deux phrases de la bccommande en plus d'un herelien serait utile.
WinEunuuchs2Unix
2

Une autre méthode peut consister à conserver vos variables sous forme d'entiers et à les convertir en chaîne à la fin:

A=12
B=$((A+1))
echo $B
13
C=$( printf '%04d' $B )
echo $C
0013

Ce style de travail avec des entiers en mathématiques et de conversion en chaîne pour la réponse est plus intuitif pour moi car je suis habitué à la programmation BASIC. J'apprécie que Bash n'ait pas de typage variable comme C et BASIC, mais prétendre qu'il le fait me rend heureux.

WinEunuuchs2Unix
la source
C'était un test pour mettre en évidence le problème que j'avais. J'ai lu la variable initiale en prenant la sortie d'une autre commande qui est du texte et a des zéros non significatifs.
Robert3452
Ah ... l'histoire explique toujours comment nous en sommes arrivés au présent.
WinEunuuchs2Unix
@ Robert3452 Vous pouvez également supprimer les zéros non A="0012"; A=$((10#$A))
significatifs