L'aggiunta di 1 a una variabile non funziona come previsto (aritmetica di Bash)


16

Se scrivo quanto segue in un terminale Bash:

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

Ottengo 11, non 13 come mi aspettavo !!!!!

Ho cercato su Google e non riesco a spiegarlo affatto, o capire come posso ottenere il numero incrementato. (In realtà voglio finire con B = "0013" e incrementarne uno ogni volta mentre lo sto usando come prefisso per i miei backup)


2
Fai attenzione agli zeri iniziali su qualsiasi linguaggio originario di UNIX. Questo normalmente significa ottale.
Giosuè,

No, non lo sei, ottieni 1011 binario
Ken Mollerup,

Risposte:


28

Questo perché i numeri che iniziano con 0sono trattati come Octal da bash, quindi sta facendo l'aggiunta di Octal (Base 8). Per ottenere l'aggiunta decimale per questa struttura, è necessario definire esplicitamente la base o non utilizzarla del 00tutto.

Per Decimale, la Base è 10, indicata da 10#:

$ A="10#0012"
$ echo $((A+1))
13

5

Puoi provare questo comando per ottenere la risposta:

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

Ulteriori informazioni sul bccomando sono disponibili qui .

bc pagina man:

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.

4
Invece di usare echoe una pipe, puoi usare la sintassi "here string" di Bash. L'effetto è lo stesso, ma IMHO la "stringa qui" è più bella: bc <<< "$A + 1":-)
Byte Commander

Sarebbe utile un'introduzione di una o due frasi del bccomando oltre a un herecollegamento.
WinEunuuchs2Unix

2

Un metodo alternativo potrebbe essere quello di mantenere le variabili come numeri interi e convertirle in una stringa alla fine:

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

Questo stile di lavoro con numeri interi in matematica e conversione in stringa per la risposta è più intuitivo per me poiché sono abituato alla programmazione BASIC. Apprezzo che Bash non abbia una digitazione variabile come C e BASIC ma fingere che mi renda felice.


Questo è stato un test per evidenziare il problema che stavo riscontrando. Ho letto la variabile iniziale prendendo l'output di un altro comando che è testo e ha zeri iniziali.
Robert3452

Ah ... la storia spiega sempre come siamo arrivati ​​al presente.
WinEunuuchs2Unix

@ Robert3452 Potresti anche eliminare gli zeri A="0012"; A=$((10#$A))
iniziali
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.