Bu komut, 5000 argüman üreten kabuk bağlıdır ve bunları geçen için printf
bu daha sonra bunları yok sayar. Oldukça hızlı görünse de - ve bazı şeylere göreceli olsa da - kabuk yine de tüm bu dizeleri argümanlar (ve onları sınırlar) olarak üretmelidir .
Oluşturulan H'lerin, kabuk ilk kez 5000'e kadar tekrarlanana kadar yazdırılamamasının yanı sıra, bu komut, sayısal dize bağımsız değişkenlerini printf
artı H'lere depolamak ve sınırlamak için gereken tüm belleğe de mal olur . Tıpkı yapabileceğiniz gibi:
printf %05000s|tr \ H
... 5000 boşluktan oluşan bir dize oluşturur - ki bu en azından genellikle başına tek bir bayttır ve sınırlandırılmadığı için sınırlandırılması hiçbir ücrete tabi değildir. Birkaç test, 5000 bayt kadar az bir süre için tr
bile, bu durumda bile çatalın ve gereken borunun maliyetinin buna değdiğini ve neredeyse her zaman sayıların arttığı zamandır.
Koştum ...
time bash -c 'printf H%.0s {1..5000}' >/dev/null
...ve...
time bash -c 'printf %05000s|tr \ H' >/dev/null
Her biri yaklaşık 5 kez bir parça (burada bilimsel bir şey yok - sadece anekdot) ve destek genişletme sürümü toplam işlem süresinde ortalama .02 saniyenin biraz üzerinde, ancak tr
sürüm ortalama olarak yaklaşık 0,012 saniyede geldi - ve tr
sürüm onu dövdü her zaman. Sürpriz olduğumu söyleyemem - {brace expansion}
kullanışlı bir interaktif kabuk stenografi özelliğidir, ancak genellikle herhangi bir komut dosyası söz konusu olduğunda yapmak oldukça zahmetli bir şeydir. Ortak form:
for i in {[num]..[num]}; do ...
... bunu düşündüğünüzde, gerçekten iki for
döngü - birincisi içseldir ve kabuğun, bunları kaydetmeden ve for
döngü için tekrar yinelemeden önce bu yineleyicileri oluşturmak için bir şekilde döngü yapması gerektiği anlamına gelir . Bu tür şeyler genellikle daha iyi yapılır:
iterator=$start
until [ "$((iterator+=interval))" -gt "$end" ]; do ...
... çünkü yalnızca çok az bir değer depolar ve yinelemeleri oluştururken yinelemeyi yaparken gittikçe bunların üzerine yazarsınız.
Her neyse, daha önce belirtilen boşluk dolgusu gibi, printf
elbette, rastgele sayıda rakamı sıfırlamak için de kullanabilirsiniz :
printf %05000d
Bir argüman bulunmadığında printf
'sd dizesinde belirtilen her argüman için null dize kullanılır - bir basamak argümanı için sıfır veya bir dize için boş bir dize olarak yorumlanır, çünkü her iki bağımsız değişken yapmam .
Bu, söz konusu komutla karşılaştırıldığında madalyonun diğer (ve bence - daha verimli) tarafıdır - printf %.0
her bir argüman için dizeleri uzatırken yaptığınız gibi bir şey almak mümkün değildir , bu yüzden de hiçbir şeyden bir şey almak mümkün.
Aşağıdaki dd
gibi kullanabileceğiniz büyük miktarda oluşturulan bayt için daha hızlı :
printf \\0| dd bs=64k conv=sync
... ve w / düzenli dosyalar dd
'ın seek=[num]
argümanı daha avantaj kullanılabilir. Eğer eklerseniz 64k yeni satır yerine boş değerlere alabilirsiniz ,unblock cbs=1
satır başına keyfi dizeleri ile orada enjekte edebilir üstünde ve ila paste
ve /dev/null
- ama bu durumda, sizin için kullanılabilir olduğunda siz de kullanabilirsiniz:
yes 'output string forever'
İşte dd
yine de bazı örnekler:
dd bs=5000 seek=1 if=/dev/null of=./H.txt
... yaratan (veya kesikler) bir \0NUL
boyut 5000 bayt H.txt adında geçerli dizinde dolu dosyayı. dd
doğrudan ofseti arar ve NUL arkasını doldurur.
<&1 dd bs=5000 conv=sync,noerror count=1 | tr \\0 H >./H.txt
... aynı ad ve büyüklükte ancak H karakterleriyle doldurulmuş bir dosya oluşturur. Bu yararlanır dd
zaman okuma hatası durumunda en az bir tam boş-bloğun yazma 'ın spec' davranış noerror
ve sync
dönüşümler belirtilmiştir (- olmadan ve count=
muhtemelen tercih edebilir daha uzun devam edecek -) yönlendirmeleri ve kasıtlı wdineonly dosya tanıtıcısı dd
.
tcsh
ya dazsh
,repeat 5000 printf H
anlamak kolaydır. İleperl
:print "H" x 5000
(o notu{1..5000}
esinlenerek Zsh operatörüdürperl
s'1..5000
bir ve daha sonra ksh93 ve bash tarafından kopyalanan)