Dodanie 1 do zmiennej nie działa zgodnie z oczekiwaniami (arytmetyka Bash)

16

Jeśli napiszę następujące w terminalu bash:

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

Dostaję 11, a nie 13, jak się spodziewałem !!!!!

Poszukałem w Google i nie mogę tego w ogóle wyjaśnić, ani wymyślić, jak mogę zwiększyć liczbę. (Właściwie chcę skończyć na B = „0013” i zwiększać jeden za każdym razem, ponieważ używam tego jako prefiksu moich kopii zapasowych)

Robert3452
źródło
2
Uwaga na wiodące zera w zasadniczo dowolnym języku pochodzącym z systemu UNIX. Zwykle oznacza to ósemkę.
Joshua
Nie, nie jesteś, dostajesz 1011 plików binarnych
Ken Mollerup,

Odpowiedzi:

28

Dzieje się tak, ponieważ liczby zaczynające się od 0są traktowane jako Liczby ósemkowe bash, stąd dodaje się Liczbę ósemkową (Podstawa 8). Aby uzyskać dodawanie dziesiętne dla tej struktury, musisz jawnie zdefiniować Podstawę lub 00całkowicie nie używać .

W przypadku wartości dziesiętnych podstawą jest 10, oznaczona przez 10#:

$ A="10#0012"
$ echo $((A+1))
13
heemayl
źródło
5

Możesz spróbować użyć tego polecenia, aby uzyskać odpowiedź:

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

Więcej informacji o bcpoleceniu można znaleźć tutaj .

bc strona podręcznika:

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.
podejrzeć
źródło
4
Zamiast używać echoi potoku, możesz użyć składni „tu string” Basha. Efekt jest taki sam, ale IMHO „ciąg tutaj” jest piękniejszy: bc <<< "$A + 1":-)
Byte Commander
Pomocne byłoby wprowadzenie jednego lub dwóch zdań bcoprócz herelinku.
WinEunuuchs2Unix
2

Alternatywną metodą może być zachowanie zmiennych jako liczb całkowitych i przekonwertowanie ich na ciąg znaków na końcu:

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

Ten styl pracy z liczbami całkowitymi w matematyce i konwersji na ciąg znaków w celu uzyskania odpowiedzi jest dla mnie bardziej intuicyjny, ponieważ jestem przyzwyczajony do programowania w języku BASIC. Rozumiem, że Bash nie ma takich zmiennych jak C i BASIC, ale udawanie, że to robi, sprawia, że ​​jestem szczęśliwy.

WinEunuuchs2Unix
źródło
To był test mający na celu podkreślenie mojego problemu. Czytam zmienną początkową, biorąc wynik innego polecenia, które jest tekstem i ma zera na początku.
Robert3452,
Ach ... historia zawsze wyjaśnia, jak doszliśmy do teraźniejszości.
WinEunuuchs2Unix
@ Robert3452 Możesz także usunąć zera wiodące:A="0012"; A=$((10#$A))
wjandrea