Làm thế nào để lặp lại một số nguyên đệm bằng 0 trong bash?


8

Làm thế nào để lặp lại một chuỗi có dạng "[AZ] [0-9] *" hoặc ví dụ: "A000001"?

Sau khi nhận được biến tôi chia:

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

Tuy nhiên khi tôi cố gắng thêm 1:

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

Nó được tính là "000009" và quay trở lại "000000".

Và tôi tham gia như sau:

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

Và liên quan đến việc lặp lại Letter tôi đã nghĩ đến việc sử dụng Associated Array? Hoặc mở rộng cú đúp {A..Z}, nhưng đó là một câu hỏi hoàn toàn khác.

Câu trả lời:


14

Trong đó bash, các số có số 0 đứng đầu được coi là số bát phân.

Bạn có thể dùng:

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

Để nói bashđể coi nó như là số thập phân.

Xem thêm:

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

Hoặc là:

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

Hoặc là:

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

5

Perl để giải cứu:

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

Đầu ra:

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

Toán tử ++ xử lý cả chữ và số.


Tôi biết perl được bao gồm trong Ubuntu, nhưng nó có phải là một bash dựng sẵn không? Tôi có chính xác 0 kinh nghiệm viết bằng perl. Điều này rõ ràng hoạt động.
jmunsch

@jmunsch: Perl không phải là một phần của bash. Đó là một ngôn ngữ lập trình của riêng nó.
choroba

Tôi đã làm một số tìm kiếm. Có vẻ như Perl đang ở trong rất nhiều bản phát hành? Và thêm một phụ thuộc vào Perl không phải là một vấn đề? Cảm ơn câu trả lời của bạn.
jmunsch

1
@jmunsch: Perl nên có trên bất kỳ Linux nào. Bạn cũng có thể tìm thấy nó hoặc cài đặt nó trên hầu hết các hệ thống * ix, cũng như MS Windows.
choroba

Đây sẽ là một câu trả lời tốt hơn perl? export current_ && perl -E 'say $ENV{current_}++'bởi vì tôi không thể nhập biến từ bash sang perl?
jmunsch

1

Vì các lý do lịch sử, các phép toán số trong các vỏ kiểu Bourne / POSIX phân tích các hằng số nguyên với một 0chữ số đứng đầu là bát phân thay vì thập phân. Vì vậy, 08trong một phép toán số học là một lỗi cú pháp, sự kế thừa 07là 8 và 010tương đương với 8.

Bạn có thể sử dụng số học bình thường và sau đó đệm số khi in chúng với printfnội trang.

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

Các -vtùy chọn để printflà bash cụ thể; cách POSIX là

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

Đây là một cách tiếp cận khác hữu ích trong các hệ thống lịch sử không có printflệnh và vẫn có thể hữu ích cho hiệu suất trong một số shell không có printftrong tích hợp. Thay vì đếm từ 1, hãy đếm từ 1000001. Bằng cách đó, số của bạn không bao giờ phải có số 0 đứng đầu. Khi bạn sử dụng số, loại bỏ 1chữ số hàng đầu .

number=1000000
while  ; do
  number=$((number+1))
  echo "${number#1}"
  
done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.