it-swarm.com.de

Wie kann man den Wert einer (dezimalen) Variablen (mit führender Null) um +1 erhöhen?

Ich habe eine Datei im Namen von Build.number mit dem Inhaltswert 12, die ich um +1 erhöhen muss. Also habe ich es versucht

BN=$($cat Build.number)
BN=$(($BN+1))
echo $BN >Build.number

aber hier bekomme ich den Wert 11, wenn ich 1 erwarte. Kann mir jemand helfen?

13
Naik

Die führende 0 bewirkt, dass Bash den Wert als Oktalwert interpretiert ; 012 Oktal ist 10 Dezimal, Sie erhalten also 11.

Um die Verwendung von Dezimalstellen zu erzwingen, fügen Sie 10# Hinzu (solange die Zahl kein führendes Vorzeichen hat):

BN=10#$(cat Build.number)
echo $((++BN)) > Build.number

Verwenden Sie printf, um die Nummer mit mindestens drei Ziffern zu drucken:

printf "%.3d\n" $((++BN)) > Build.number
32
Stephen Kitt

bash behandelt Konstanten, die mit 0 beginnen, als Oktalzahlen in ihren arithmetischen Ausdrücken, sodass 011 tatsächlich 9 ist.

Das ist eigentlich eine POSIX-Anforderung.

Einige andere Shells wie mksh oder zsh ignorieren es (außer im POSIX-kompatiblen Modus), da es weitaus häufiger im Weg steht, als es nützlich ist.

Mit ksh93 gibt BN=011; echo "$(($BN))"9 aus, aber echo "$((BN))" gibt 11 aus.

In bash können Sie BN=$((10#$(<Build.number))) verwenden, was funktionieren sollte, solange die Nummer nicht mit - oder + beginnt.

18

In jeder POSIX-Shell können Sie verhindern, dass eine Zahl als oktal betrachtet wird, indem Sie ihre führenden Nullen mit einer Kombination der Erweiterungsformen ${var#prefix} Und ${var%%suffix} Entfernen:

BN=001002; BN=$(( ${BN#${BN%%[!0]*}} + 1 )); echo "$BN"
1003

In Shells, die die Syntax ${var//pat/repl} Unterstützen, können Sie dies auch tun, indem Sie 1 Vorstellen und von 10^{number_of_digits} Subtrahieren:

BN=000012; BN=$(( 1$BN - 1${BN//?/0} )); echo "$BN"; BN=$((BN+1)); echo "$BN"
12
13

Dies funktioniert in bash, zsh, ksh93, mksh und yash.

In bash, ksh93 Und zsh (aber nicht in yash und mksh) können Sie auch den fortranish ** Operator (Potenzierung):

BN=000012; BN=$(( 1$BN - 10**${#BN} ))
4
mosvy

Hier ist eine Funktion zum Inkrementieren einer numerischen Zeichenfolge. Es beobachtet führende Nullen und versucht, die Anzahl der Ziffern beizubehalten. Es verwendet keine Variablen, benötigt also keine Shell-Erweiterung zum Deklarieren lokaler Variablen und verschmutzt den Variablennamensraum nicht:

# $1 -- decimal string, possibly with leading zeros or sign
# $2 -- integer increment, no leading zeros.
incnumstr()
{
  if [ $1 -lt 0 ] ; then
    set -- $(incnumstr ${1#-} $((- $2)))
    [ $1 -le 0 ] && printf "%s" ${1#-}  \
                 || printf "%s" -$1
    return
  fi

  set -- ${1#-} $2 # strip leading minus from zero

  [ $1 -eq 0 ] && printf "%s%0.*d" "$3" ${#1} $2 \
               || printf "%s%0.*d" "$3" ${#1} $(( ${1#${1%%[1-9]*}} + $2 ))
}

Interaktive Tests:

$ echo $(incnumstr 0 0)
0
$ echo $(incnumstr -0 0)
0
$ echo $(incnumstr 0 1)
1
$ echo $(incnumstr 0 -1)
-1
$ echo $(incnumstr 00 1)
01
$ echo $(incnumstr 00 -1)
-01
$ echo $(incnumstr -10 10)
00
$ echo $(incnumstr -10 11)
01
$ echo $(incnumstr -10 20)
10
$ echo $(incnumstr -10 99)
89
$ echo $(incnumstr -10 110)
100
$ echo $(incnumstr 100 -90)
010
$ echo $(incnumstr 100 -99)
001
$ echo $(incnumstr 100 -100)
000
$ echo $(incnumstr 100 -101)
-001
$ echo $(incnumstr 100 -1234)
-1134
$ echo $(incnumstr -0000 0)
0000
$ echo $(incnumstr -0000 1)
0001
$ echo $(incnumstr -0000 -2)
-0002
0
Kaz