2017-09-18 7 views
1

In meinem Bash-Skript integer Längen Festsetzung ich Set-up die folgenden Operationenseltsames Verhalten, wenn in bash

year=0050 
echo $(printf %04d $year) 
>0040 

Ich verstehe nicht, warum 0040 statt 0050. zurückgegeben ich schließlich, dass gefunden, das System zu erhalten um 0050 korrekt auszudrucken, muss ich dies stattdessen tun.

year=50 
echo $(printf %04d $year) 
>0050 

Gibt es irgendwelche Einsichten, warum der erste Fall passiert?

+5

Wenn Sie Ihre Nummer mit '0' beginnen, wird sie als oktal interpretiert; Oktal 50 ist Dezimal 40. –

+1

Numerische Argumente zu 'printf' mit einer führenden '0' werden als Oktalzahlen interpretiert. Warum rufen Sie auch 'echo $ (printf ...)'? "echo" und "printf" drucken beide ihre Ausgabe. Sie können das Echo löschen. – larsks

+0

@larks Das liegt vielleicht an Zeilenumbrüchen, aber offensichtlich ist das besser mit '% 04d \ n' gelöst. –

Antwort

2

Es ist, weil Zahlen mit einer führenden Null als Oktal von Bash interpretiert werden, und 50 Oktal ist dezimal 40.

es zu beheben, können Sie entweder die Nullen mit einem Parameter Expansion Streifen:

$ printf '%04d\n' "${year##+(0)}" 
0050 

Ich habe das echo $(...) Konstrukt gelöscht und stattdessen eine neue Zeile in die Formatierungszeichenfolge eingefügt.

Beachten Sie, dass das Muster +(0) die Shell-Option extglob erfordert (shopt -s extglob).

Alternativ (und mehr portabel), können Sie die Nummer mit einer arithmetischen Erweiterung zuerst konvertieren:

% printf '%04d\n' "$((10#$year))" 
0050 

Dies verwendet die base#n Notation, um anzuzeigen, dass n (in unserem Fall: $year) in der Basis ist 10 und nicht oktal.