Das Hinzufügen von 1 zu einer Variablen funktioniert nicht wie erwartet (Bash-Arithmetik)

16

Wenn ich Folgendes in ein Bash-Terminal schreibe:

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

Ich bekomme 11, nicht 13, wie ich erwartet hatte !!!!!

Ich habe herumgegoogelt und kann es überhaupt nicht erklären oder herausfinden, wie ich die Zahl erhöhen kann. (Eigentlich möchte ich am Ende B = "0013" haben und jedes Mal eins erhöhen, wenn ich dies als Präfix für meine Backups verwende.)

Robert3452
quelle
2
Hüten Sie sich vor führenden Nullen in praktisch jeder Sprache, die auf UNIX basiert. Dies bedeutet normalerweise oktal.
Joshua
Nein, du bist nicht du bekommst 1011 Binär
Ken Mollerup

Antworten:

28

Das liegt daran, dass Zahlen, die mit beginnen, von 0als Oktal behandelt werden bash, daher wird eine Oktaladdition (Basis 8) durchgeführt. Um die Dezimaladdition für diese Struktur zu erhalten, müssen Sie die Basis explizit definieren oder nicht zusammen verwenden 00.

Für Decimal ist die Basis 10, angegeben durch 10#:

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

Sie können diesen Befehl versuchen, um die Antwort zu erhalten:

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

Weitere Informationen zum bcBefehl finden Sie hier .

bc Manpage:

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.
schnüffeln
quelle
4
Anstelle von echound einer Pipe können Sie auch die "here string" -Syntax von Bash verwenden. Der Effekt ist der gleiche, aber meiner Meinung nach ist der "Hier-String" schöner: bc <<< "$A + 1":-)
Byte Commander
Eine Einführung des bcBefehls mit ein oder zwei Sätzen zusätzlich zu einem hereLink wäre hilfreich.
WinEunuuchs2Unix
2

Eine alternative Methode kann darin bestehen, Ihre Variablen als Ganzzahlen beizubehalten und sie am Ende in eine Zeichenfolge zu konvertieren:

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

Diese Art der Arbeit mit Ganzzahlen in Mathematik und das Umwandeln in Zeichenfolgen für die Antwort ist für mich intuitiver, da ich an die BASIC-Programmierung gewöhnt bin. Ich schätze, dass Bash keine Variablentypen wie C und BASIC hat, aber so zu tun, als wäre ich glücklich.

WinEunuuchs2Unix
quelle
Dies war ein Test, um das Problem hervorzuheben, das ich hatte. Ich habe die anfängliche Variable gelesen, indem ich die Ausgabe eines anderen Befehls genommen habe, der Text ist und führende Nullen hat.
Robert3452
Ah ... die Geschichte erklärt immer, wie wir zur Gegenwart gekommen sind.
WinEunuuchs2Unix
@ Robert3452 Sie können auch führende Nullen A="0012"; A=$((10#$A))
entfernen