2009-12-14 20 views
13

Làm cách nào để kiểm tra biến int ($ inputNo) để xem có từ 2 chữ số thập phân trở lên không?Hãy chắc chắn rằng biến int dài 2 chữ số, thêm 0 vào trước để làm cho nó dài 2 chữ số

Ví dụ:

inputNo="5" 

nên được thay đổi để: 05

inputNo="102" 

nên bị bỏ lại một mình: 102

Tôi nghĩ về việc sử dụng wcif báo cáo, nhưng wc -m không dường như cung cấp cho các ký tự thực tế được chuyển vào wc, như wc luôn thấy ms để cung cấp +1 cho các ký tự được cung cấp.

Nhưng tôi không biết cách thêm số 0 vào trước số đầu vào hiện tại.

Trả lời

32

Bạn có thể sử dụng bash-BUILTIN printf với các tùy chọn -v để viết nó vào một biến chứ không phải in nó để đầu ra tiêu chuẩn:

pax> inputNo=5 ; printf -v inputNo "%02d" $inputNo ; echo $inputNo 
05 
pax> inputNo=102 ; printf -v inputNo "%02d" $inputNo ; echo $inputNo 
102 

Bạn sẽ muốn đảm bảo đó là số đầu tiên nếu không chuyển đổi sẽ không thành công. Nếu bạn muốn để có thể pad bất kỳ chuỗi ra hai hoặc nhiều ký tự, bạn cũng có thể sử dụng:

while [[ ${#inputNo} -lt 2 ]] ; do 
    inputNo="0${inputNo}" 
done 

mà về cơ bản là một vòng lặp while rằng tiền tố chuỗi của bạn với "0" cho đến khi chiều dài lớn hơn hoặc bằng hai.

Lưu ý rằng điều này cũng có thể được thực hiện trong bash bằng cách đặt trước số với hai số không sau đó chỉ cần nhận được hai ký tự cuối cùng của chuỗi, kiểm tra đầu tiên mà nó chưa được tối thiểu kích thước mong muốn:

if [[ ${#inputNo} -lt 2 ]] ; then 
    inputNo="00${inputNo}" 
    inputNo="${inputNo: -2}" 
fi 

Sự khác biệt có lẽ không quá lớn đối với số có hai chữ số nhưng bạn có thể thấy giải pháp thứ hai tốt hơn nếu bạn cần chiều rộng lớn hơn.


Nếu bạn đang sử dụng một vỏ khác hơn bash (không, dựa trên các thẻ của bạn), bạn sẽ cần phải tìm ra tương đương, hoặc trở lại với việc sử dụng các quy trình bên ngoài để làm việc, cái gì đó như :

while [[ $(echo -n ${inputNo} | wc -c) -lt 2 ]] ; do 
    inputNo="0${inputNo}" 
done 

này làm cơ bản những gì bạn đang nghĩ ra trong câu hỏi của bạn, nhưng lưu ý việc sử dụng -n trong lệnh echo để ngăn chặn các ký tự dòng mới (được gần như chắc chắn gây off-by-one của bạn lỗi).

Nhưng, như đã nêu, đây là vị trí lùi. Nếu bạn đang sử dụng bash, các đề xuất trước đây của tôi có lẽ là tốt nhất.

+0

Cảm ơn! Hoạt động tuyệt vời. – Mint

+0

Không cần các quy trình bên ngoài trong trường hợp chung: 'while test" $ {# inputNo} "-lt 2; do inputNo = "0 $ inputNo"; done' (* [[* thay đổi thành * test * với trích dẫn thêm để làm cho nó tương thích với nhiều shell hơn). –

+0

Không cần mở rộng bash ($ {# ...}): 'case $ inputNo in [0-9]) inputNo =" 0 $ inputNo ";; *) ;; esac'. – Idelic

1

Bạn có thể sử dụng http://bash-hackers.org/wiki/doku.php/commands/builtin/printf, một ví dụ từ đó:

the_mac="0:13:ce:7:7a:ad" 

# lowercase hex digits 
the_mac="$(printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${the_mac//:/ 0x})" 

# or the uppercase-digits variant 
the_mac="$(printf "%02X:%02X:%02X:%02X:%02X:%02X" 0x${the_mac//:/ 0x})" 
+0

Cảm ơn bạn đã liên kết, tôi luôn thích đọc làm thế nào một chức năng hoạt động và tất cả những gì nó có thể làm. – Mint

6

Đối với mục đích chung đệm liệu chuỗi là số hay không

Không cần cho đường ống echo vào wc hoặc sử dụng một vòng lặp while.

Trong Bash, bạn có thể nhận được độ dài của chuỗi như sau: ${#inputNo}.

Và kể từ khi bạn có thể làm chuỗi con, bạn có thể làm điều này thay vì:

if [[ ${#input} < 2 ]] 
then 
    inputNo="00${inputNo}" 
    inputNo="${inputNo: -2}" 
fi 
Các vấn đề liên quan