Cách tạo một chuỗi với các số 0 đứng đầu bằng cách sử dụng mở rộng dấu ngoặc


45

Khi tôi sử dụng như sau, tôi nhận được một kết quả như mong đợi:

$ echo {8..10}
8 9 10

Làm thế nào tôi có thể sử dụng mở rộng niềng răng này một cách dễ dàng, để có được đầu ra sau đây?

$ echo {8..10}
08 09 10

Bây giờ tôi có thể lấy được bằng cách sử dụng seq(không thử), nhưng đó không phải là thứ tôi đang tìm kiếm.

Thông tin hữu ích có thể là tôi bị hạn chế trong phiên bản bash này. (Nếu bạn có zshgiải pháp, nhưng không có bashgiải pháp, vui lòng chia sẻ)

$ bash -version
GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu)

Một số gợi ý để làm điều này trong bash 3 Tôi tìm thấy ở đây: mywiki.wooledge.org/BashFAQ/018 Tuy nhiên, cách tiếp cận được nêu ở đó không thuận tiện.
Bernhard

Câu trả lời:


70

Tiền tố số đầu tiên với a 0để buộc mỗi thuật ngữ có cùng chiều rộng.

$ echo {08..10}
08 09 10

Từ phần trang bash man trên Brace Expansion:

Các số nguyên được cung cấp có thể có tiền tố bằng 0 để buộc mỗi số hạng có cùng độ rộng. Khi x hoặc y bắt đầu bằng 0, hệ vỏ cố gắng buộc tất cả các thuật ngữ được tạo phải chứa cùng một số chữ số, không đệm khi cần thiết.

Cũng lưu ý rằng bạn có thể sử dụng seqvới -wtùy chọn để cân bằng chiều rộng bằng cách đệm với các số 0 đứng đầu:

$ seq -w 8 10
08
09
10

$ seq -s " " -w 8 10
08 09 10

Nếu bạn muốn kiểm soát nhiều hơn, bạn thậm chí có thể chỉ định định dạng kiểu printf:

$ seq -s " " -f %02g 8 10
08 09 10

8
Sau khi tìm hiểu về echo {08..10}giải pháp, tuy nhiên, nó chỉ được giới thiệu cho bash phiên bản 4 trở lên.
Bernhard

Điều đó làm tôi hơi khó chịu khi bash làm điều đó. Đối với một loạt các tiện ích (ví dụ perl), số 0 đứng đầu biểu thị số bát phân. Tôi cho rằng không thường xuyên bạn muốn có một dãy số bát phân ...
kurtm

5
Cần lưu ý rằng bạn cũng có thể đặt tiền tố cho các số khi đưa ra sau đó seqvới công -wtắc như vậy: seq -w 003tạo ra các số 001, 002 và 003.
slm

@kurtm đừng lo lắng về số không hàng đầu. Điều đó có thể đau khi một cái gì đó cố gắng phân tích một số. Điều này thực sự hữu ích là tạo ra một chuỗi tên tệp foo_00001.someextensiontrong đó gần như tất cả các bối cảnh sắp xếp cung cấp một thứ tự lành mạnh.
Stéphane Gourichon

9

nếu bạn sử dụng printf

printf "%.2d " {8..10} 

điều này sẽ buộc thành 2 ký tự và sẽ thêm một số 0. Trong trường hợp bạn cần 3 chữ số, bạn có thể đổi thành "% .3d".


Cảm ơn câu trả lời của bạn. Tôi nhận thức được printfgiải pháp, nhưng nó không thực sự làm cho việc này dễ dàng hơn. Tôi hy vọng rằng có một số mẹo ẩn thực hiện công việc :)
Bernhard

Đây là câu trả lời duy nhất có vẻ linh hoạt đủ để xử lý mọi tình huống về nguồn gốc của số để đệm. Tôi đang sử dụng một bộ đếm khi tôi lặp qua các tập tin. Giải pháp printf này không có phần đệm hoàn hảo trong khi tất cả các phần khác dường như tập trung vào việc tạo ra các số có phần đệm thay vì số không có phần đệm.
mightypile

7

Sử dụng một phạm vi bắt đầu bằng một chữ số không đổi và loại bỏ chữ số đó:

echo \ {108..110} | sed 's/ 1//g'

hoặc không sử dụng lệnh bên ngoài:

a=({108..110}); echo "${a[@]#1}"

Để sử dụng trong một vòng lặp for:

for x in {108..110}; do
  x=${x#1}
  
done

mặc dù trong trường hợp này, một vòng lặp while sẽ rõ ràng hơn và hoạt động trong bất kỳ shell POSIX nào:

x=8
while [ $x -le 10 ]; do
  n=$((100+x)); n=${n#1}
  
  x=$((x+1))
done

Tôi đã chấp nhận câu trả lời này trên các câu trả lời khác, vì nó đáp ứng yêu cầu cho Bash 3.x. Đặc biệt là fordù sao tôi cũng cần vòng lặp.
Bernhard

6

Tôi có cùng phiên bản bash của poster gốc ( GNU bash, version 3.2.51(1)-release) và {08..12}không hoạt động với tôi, nhưng sau đây có:

for i in 0{8..9} {10..12}; do echo $i; done
08
09
10
11
12

Nó hơi tẻ nhạt hơn một chút, nhưng nó hoạt động trên phiên bản OP của bash (và các phiên bản mới hơn, tôi sẽ giả sử).


Tôi đã không nghĩ về giải pháp này (mặc dù trong trường hợp của tôi, tôi thực sự cũng muốn số 0001 1000, nhưng tất nhiên nguyên tắc của bạn hoạt động.
Bernhard

1

Để tham khảo, tôi nghĩ rằng chiều rộng cố định tự động chỉ xảy ra với phiên bản bash mới nhất:

$ bash -version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

$ echo test{00..05}
test0 test1 test2 test3 test4 test5

-3
for i in $(seq -s " " -f %0${zeros}g $ini $fin); do ....;done

số không, ini và vây là vars, vì vậy thật dễ dàng, bạn chỉ viết các số không mà bạn nói bằng 'số không' để ini thành vây mà không gặp vấn đề gì;)

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.