2012-01-09 22 views
261

tôi cần để lặp một số giá trị,Làm thế nào để không pad một chuỗi các số nguyên trong bash để tất cả đều có cùng chiều rộng?

for i in $(seq $first $last) 
do 
    does something here 
done 

Đối $first$last, tôi cần nó để có độ dài cố định 5. Vì vậy, nếu đầu vào là 1, tôi cần phải thêm số không trước mặt như vậy mà nó trở thành 00001 . Nó vòng đến 99999 ví dụ, nhưng chiều dài phải là 5.

ví dụ .: 00002, 00042, 00212, và vân vân.

Bất kỳ ý tưởng nào về cách tôi có thể làm điều đó?

+10

Một câu trả lời tốt có thể là: seq - w 1 99999. Lựa chọn -w giữ đầu ra chiều dài không đổi, đệm số ngắn nhất với 0. –

+0

Cũng đổi tên tập tin: http: // stackoverflow.com/questions/55754/bash-script-to-pad-file-names –

Trả lời

440

Trong trường hợp cụ thể của bạn mặc dù nó có thể là đơn giản nhất để sử dụng -f cờ để seq để có được nó để định dạng số như nó ra danh sách. Ví dụ:

for i in $(seq -f "%05g" 10 15) 
do 
    echo $i 
done 

sẽ cho kết quả sau:

00010 
00011 
00012 
00013 
00014 
00015 

Tổng quát hơn, bashprintf như một built-in để bạn có thể đầu ra pad với zero như sau:

$ i=99 
$ printf "%05d\n" $i 
00099 

Bạn có thể sử dụng cờ -v để lưu trữ kết quả trong một biến khác:

$ i=99 
$ printf -v j "%05d" $i 
$ echo $j 
00099 

Lưu ý rằng printf hỗ trợ định dạng hơi khác với seq vì vậy bạn cần sử dụng %05d thay vì %05g.

+1

'% 05g' thay vì'% 05d' đã sửa nó cho tôi. _ "00026" _ đã cho tôi _ "00022" _. Cảm ơn! –

+6

Câu trả lời tuyệt vời, toàn diện. Một sửa đổi nhỏ: nói đúng, 'seq' hỗ trợ _subset_ của các ký tự định dạng. 'printf' hỗ trợ (và các tập con đó bao gồm' g', nhưng không phải 'd'). Hành vi của các ký tự 'd' và' g' khác nhau một cách tinh tế trong đó 'd' diễn giải' 0' có số tiền tố là chuỗi _octal_ và chuyển đổi thành số thập phân, trong khi 'g' coi chúng là số thập phân. (@EdManet: đó là lý do tại sao '00026' chuyển thành '00022' với 'd'). Một điều đáng nhắc đến khác: 'seq-w' thực hiện _automatic_ zero-padding của các số đầu ra dựa trên số lớn nhất được tạo ra. – mklement0

+0

Điều này đã giúp tôi tạo danh sách ký tự hex. 'for ((i = 0; i <= 0xffffffff; i ++)) làm printf"% 08x \ n "$ i; xong >> hex.txt' đã tạo danh sách thập lục phân 8 ký tự. Cảm ơn. – cde

56

sử dụng printf với "% 05d", ví dụ:

printf "%05d" 1 
13

Rất đơn giản sử dụng printf

[jaypal:~/Temp] printf "%05d\n" 1 
00001 
[jaypal:~/Temp] printf "%05d\n" 2 
00002 
9

Sử dụng awk như thế này:

awk -v start=1 -v end=10 'BEGIN{for (i=start; i<=end; i++) printf("%05d\n", i)}' 

OUTPUT:

00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 

Cập nhật:

Như tinh khiết bash thay thế, bạn có thể làm điều này để có được cùng một kết quả:

for i in {1..10} 
do 
    printf "%05d\n" $i 
done 

Bằng cách này bạn có thể tránh sử dụng một chương trình bên ngoài seq đó là KHÔNG sẵn trên tất cả các hương vị của * nix.

+1

Chúng ta có thể sử dụng câu lệnh 'awk's'' BEGIN' để chúng ta không phải sử dụng phép gán 'heredoc'. –

+0

@JaypalSingh: Cảm ơn bạn đời, đó là một điểm tốt. Đã cập nhật câu trả lời của tôi. – anubhava

80

dễ dàng hơn bạn vẫn chỉ có thể làm

for i in {00001..99999}; do 
    echo $i 
done 
+12

Tính năng này hoạt động trên phiên bản Bash 4.1.2 (CentOS 6) nhưng không hoạt động trong phiên bản 3.2.25 (CentOS 5). Tôi đồng ý rằng đây là cách làm đẹp hơn nhiều về mặt thẩm mỹ để làm điều đó! –

+0

Hoạt động, nhưng không cung cấp chuỗi không có đệm trên bash – user2707001

43

Nếu cuối chuỗi có chiều dài tối đa của đệm (ví dụ, nếu bạn muốn 5 chữ số và lệnh là "seq 1 10000"), hơn bạn có thể sử dụng "-w" cờ cho seq - nó thêm padding chính nó.

seq -w 1 10 

sản xuất

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
+2

Đây rõ ràng là câu trả lời đúng. Tại sao nó có rất ít upvotes? – adius

+2

dễ dàng, bởi vì phần đệm phụ thuộc vào số lượng tối đa bạn muốn tiếp cận. Nếu đây là thông số bạn chưa bao giờ biết trước bao nhiêu số không, bạn sẽ kết thúc với – guillem

+1

Điều này không cung cấp độ dài cố định được chỉ định, chỉ là kết quả là tất cả độ dài _same_. – Ceisc

5

ra tôi pad với nhiều chữ số (số không) hơn tôi cần sau đó sử dụng đuôi để chỉ sử dụng số lượng chữ số Tôi đang tìm kiếm. Lưu ý rằng bạn phải sử dụng '6' trong đuôi để có được năm chữ số cuối cùng :)

for i in $(seq 1 10) 
do 
RESULT=$(echo 00000$i | tail -c 6) 
echo $RESULT 
done 
+0

Nếu bạn muốn sử dụng đúng số vị trí trong đối số -c của đuôi, bạn có thể sử dụng 'echo -n 00000 $ i' vì điều này dừng nó xuất ra một dòng mới là một trong các đuôi ký tự quay trở lại, do đó nó cần cao hơn trong câu trả lời này. Tùy thuộc vào những gì bạn đang làm, dòng mới, nếu trái, có thể ảnh hưởng đến kết quả. – Ceisc

2

Nếu bạn muốn chữ số N, thêm 10^N và xóa chữ số đầu tiên.

for ((num=100; num<=105; num++)) 
do 
    echo ${num:1:3} 
done 

Output:

01 
02 
03 
04 
05 
Các vấn đề liên quan