
Wie iteriert man einen String der Form "[AZ][0-9]*" oder zum Beispiel: "A000001"?
Nach Erhalt der Variable habe ich aufgeteilt:
current_=$(mysql -h"$mysqlhost" -u"$mysqluser" -p"$PASS" "$DBNAME" -se "SELECT current_ FROM $GLOBALDB;")
current_number=$(echo $current_ | grep -oh "[0-9]*")
current_letter=$(echo $current_ | grep -oh "[A-Z]*")
Wenn ich jedoch versuche, 1 hinzuzufügen:
# add 1 & keep all leading zeros "000001"
next_number=$(printf %06d $(($current_number + 1)))
Es zählt bis „000009“ und geht dann zurück auf „000000“.
Und ich schließe mich wie folgt an:
next_=$(echo "$current_letter$next_number")
Und in Bezug auf die Buchstabeniteration dachte ich an die Verwendung eines assoziierten Arrays? Oder einer Klammererweiterung {A..Z}
, aber das ist eine ganz andere Frage.
Antwort1
In bash
werden Zahlen mit führenden Nullen als Oktalzahlen betrachtet. Um zu erzwingen, bash
dass sie als Dezimalzahlen betrachtet werden, können Sie ein 10#
Präfix hinzufügen:
next_number=$(printf %06d "$((10#$current_number + 1))")
Oder mit Bash 3.1 oder höher, um die Aufspaltung zu vermeiden:
printf -v next_number %06d "$((10#$current_number + 1))"
(Beachten Sie, dass dies nicht für negative Zahlen funktioniert, wie in 10#-010
zu sehen ist , also werden sowohl als auch zu erweitert ).10#0 - 010
bash
$((10#-10))
$((-10#-10))
-8
Siehe auch:
$ printf 'A%06d\n' {5..12}
A000005
A000006
A000007
A000008
A000009
A000010
A000011
A000012
Oder:
$ printf '%s\n' {A..C}{00008..00012}
A00008
A00009
A00010
A00011
A00012
B00008
B00009
B00010
B00011
B00012
C00008
C00009
C00010
C00011
C00012
Oder:
$ seq -f A%06g 5 12
A000005
A000006
A000007
A000008
A000009
A000010
A000011
A000012
Antwort2
Perl zur Rettung:
perl -E '$x = "A001"; say $x++ for 1 .. 1002'
Ausgabe:
A001
A002
A003
A004
A005
A006
A007
A008
A009
A010
A011
...
A996
A997
A998
A999
B000
B001
B002
Der ++-Operator verarbeitet sowohl Buchstaben als auch Zahlen.
Antwort3
Aus historischen Gründen analysieren numerische Operationen in Shells im Bourne/POSIX-Stil ganzzahlige Konstanten mit einer führenden 0
Ziffer als Oktal- statt als Dezimalzahlen. 08
In einer arithmetischen Operation ist also ein Syntaxfehler, der Nachfolger von 07
ist 8 und 010
entspricht 8
.
Sie können die normale Arithmetik verwenden und die Zahlen dann beim Drucken mit der printf
integrierten Funktion auffüllen.
next_number=$(($current_number + 1))
printf -v padded_next_number %06d "$next_number"
Die -v
Option printf
ist bash-spezifisch; die POSIX-Methode ist
next_number=$(($current_number + 1))
padded_next_number=$(printf %06d "$next_number")
Hier ist ein anderer Ansatz, der in historischen Systemen ohne Befehl nützlich war printf
und in den wenigen Shells, die keinen printf
integrierten Befehl haben, immer noch für die Leistung nützlich sein kann. Anstatt von 1 zu zählen, zählen Sie von 1000001. Auf diese Weise müssen Ihre Zahlen nie führende Nullen haben. Wenn Sie die Zahl verwenden, entfernen Sie die führende 1
Ziffer.
number=1000000
while … ; do
number=$((number+1))
echo "${number#1}"
…
done