Parantez genişletme kullanarak baştaki sıfırlarla bir dizi oluşturma


45

Aşağıdakileri kullandığımda, beklendiği gibi bir sonuç alıyorum:

$ echo {8..10}
8 9 10

Aşağıdaki çıktıyı elde etmek için bu ayraç genişlemesini kolay bir şekilde nasıl kullanabilirim?

$ echo {8..10}
08 09 10

Şimdi bunun elde edilebileceği seq(denememiş) olabilir, ancak aradığım şey bu değil.

Yararlı bilgiler, bu bash sürümüyle sınırlı olduğum olabilir. (Bir zshçözümünüz varsa ancak bashçözüm yoksa , lütfen paylaşın)

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

Bash 3 bunu yapmak için bazı ipucu Burada buldum: mywiki.wooledge.org/BashFAQ/018 Ancak, burada belirtilen yaklaşım uygun değildir.
Bernhard

Yanıtlar:


70

0Her terimi aynı genişliğe sahip olmaya zorlamak için ilk sayıyı a ile önekleyin.

$ echo {08..10}
08 09 10

Brace Expansion ile ilgili bash adam sayfası bölümünden:

Verilen tam sayılar, her bir terimin aynı genişliğe sahip olması için 0 ile önceden eklenebilir. X veya y sıfırla başladığında, kabuk, üretilen tüm terimleri aynı sayıdaki rakamları, zorunlu olarak sıfırla doldurmaya zorlamaya çalışır.

Ayrıca , önde gelen sıfırlarla doldurularak genişliği eşitleme seçeneğiyle seqbirlikte kullanabileceğinizi unutmayın -w:

$ seq -w 8 10
08
09
10

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

Daha fazla kontrol istiyorsanız, bir printf stili formatı bile belirleyebilirsiniz:

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

8
echo {08..10}Ancak çözüm hakkında yeni bir şey öğrenildikten sonra, yalnızca bash 4 ve üstü sürümleri için tanıtıldı.
Bernhard

Bu beni biraz rahatsız ediyor, bash bunu yapıyor. Bir grup yardımcı program için (örneğin perl) baştaki sıfır, sekizli bir sayıyı gösterir. Sanırım sık sık bir sekizli sayı dizisi
istemeniz gerekmiyor

5
Ayrıca seq, -wanahtar ile aynı şekilde verirken sayıları önekleyebileceğinize dikkat edilmelidir : seq -w 003001, 002 ve 003 sayılarını üretir.
slm

@kurtm önde gelen sıfırlar için endişelenmeyin. Bir şey bir sayıyı ayrıştırmaya çalıştığında bu acıtabilir. Bunun gerçekten yararlı foo_00001.someextensionolduğu, neredeyse tüm sıralama bağlamlarının akıllıca bir sıralama sağladığı bir dosya adı dizisi oluşturmaktır .
Stéphane Gourichon

9

Eğer printf kullanıyorsanız

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

bu 2 karakter olmaya zorlar ve baştaki 0 ​​ekler. 0 basamak olması durumunda "% .3d" olarak değiştirebilirsiniz.


Cevabınız için teşekkürler. printfÇözümün farkındayım , ama bunu gerçekten kolaylaştırmıyor. İşi yapan bazı gizli numaralar olduğunu umuyorum :)
Bernhard

Bu, sayının dolması için herhangi bir koşulun üstesinden gelebilecek kadar çok yönlü görünen tek cevaptır. Dosyaları arasında döngü gibi bir sayaç kullanıyorum. Bu printf çözümü, sıfır pedleri kusursuzca doldururken, diğerleri de sıfır dolgusu mevcut sayılar yerine sıfır dolgulu sayılar üretmeye odaklanmış gibi görünmektedir.
kudretli

7

Sabit bir rakamla başlayan bir aralık kullanın ve rakamı sıyırın:

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

veya harici bir komut kullanmadan:

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

Bir for döngüsünde kullanım için:

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

Bu durumda bir süre döngü daha net olurdu ve herhangi bir POSIX kabuğunda çalışır:

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

Bu cevabı diğer cevapların üstünde kabul ettim, çünkü Bash 3.x'in talebini yerine getiriyor. Özellikle de fordöngüye ihtiyacım olduğu gibi .
Bernhard

6

Orijinal posterin ( GNU bash, version 3.2.51(1)-release) aynı bash sürümüne sahibim ve {08..12}benim için çalışmıyor, fakat aşağıdakiler var:

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

Biraz daha sıkıcı, ancak bash'ın OP versiyonunda çalışıyor (ve daha sonraki versiyonlarda, sanırım).


Bu çözümü düşünmedim (benim durumumda aslında 0001 1000 numaralı numarayı da istiyorum, ancak sizin temel işleriniz elbette.
Bernhard

1

Başvuru için, otomatik sabit genişliğin yalnızca bash'ın en son sürümüyle gerçekleştiğini düşünüyorum:

$ 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ıfırlar, ini ve fin değişkenlerdir, bu yüzden kolaydır, sadece ini'nin problemsiz şekilde bitirmesi için 'sıfır' dediğiniz sıfırları yazarsınız;)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.