如何在 bash 中迭代零填充整數?

如何在 bash 中迭代零填充整數?

如何迭代“[AZ][0-9]*”形式的字串,或例如:“A000001”?

收到變數後我拆分:

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]*")

但是當我嘗試添加 1 時:

# add 1 & keep all leading zeros "000001"
next_number=$(printf %06d $(($current_number + 1)))

它計數到“000009”並回滾到“000000”。

我加入如下:

next_=$(echo "$current_letter$next_number")

關於字母迭代,我正在考慮使用關聯數組?或者大括號擴展{A..Z},但這是一個完全不同的問題。

答案1

在 中bash,帶有前導零的數字被視為八進位。要強制bash將它們視為十進制,您可以添加10#前綴:

next_number=$(printf %06d "$((10#$current_number + 1))")

或使用 bash 3.1 或更高版本,以避免分叉:

printf -v next_number %06d "$((10#$current_number + 1))"

(請注意,它不適用於負數,如中10#-010所示,因此和都擴展到)。10#0 - 010bash$((10#-10))$((-10#-10))-8

也可以看看:

$ printf 'A%06d\n' {5..12}
A000005
A000006
A000007
A000008
A000009
A000010
A000011
A000012

或者:

$ printf '%s\n' {A..C}{00008..00012}
A00008
A00009
A00010
A00011
A00012
B00008
B00009
B00010
B00011
B00012
C00008
C00009
C00010
C00011
C00012

或者:

$ seq -f A%06g 5 12
A000005
A000006
A000007
A000008
A000009
A000010
A000011
A000012

答案2

Perl 來拯救:

perl -E '$x = "A001"; say $x++ for 1 .. 1002' 

輸出:

A001
A002
A003
A004
A005
A006
A007
A008
A009
A010
A011
...
A996
A997
A998
A999
B000
B001
B002

++ 運算子可以處理字母和數字。

答案3

由於歷史原因,Bourne/POSIX 風格 shell 中的數值運算會將前導0數字的整數常數解析為八進位而不是十進位。所以08在算術運算中是一個語法錯誤, 的後繼07是 8,並且010等價於8

您可以使用普通算術,然後在使用內建函數列印數字時填入數字printf

next_number=$(($current_number + 1))
printf -v padded_next_number %06d "$next_number"

-v的選項是printfbash 特定的; POSIX 方式是

next_number=$(($current_number + 1))
padded_next_number=$(printf %06d "$next_number")

這是另一種方法,它在沒有命令的歷史系統中很有用printf,並且在少數沒有printf內建命令的 shell 中仍然可以提高效能。不要從 1 開始計數,而是從 1000001 開始計數。使用該號碼時,請取下前導1數字。

number=1000000
while … ; do
  number=$((number+1))
  echo "${number#1}"
done

相關內容