यह कमांड 5000 तर्क उत्पन्न करने वाले शेल पर निर्भर करता है, और उन्हें पास करने के printfबाद उन्हें अनदेखा कर देता है। हालांकि यह बहुत जल्दी लग सकता है - और कुछ चीजों के सापेक्ष है - शेल को अभी भी उन स्ट्रिंग्स के सभी उत्पन्न होना चाहिए (और उन्हें सीमांकित करें) और इसी तरह।
इस तथ्य के अलावा कि उत्पन्न Hs को तब तक मुद्रित नहीं किया जा सकता है जब तक कि शेल पहले 5000 तक पुनरावृत्त नहीं हो जाता है, उस आदेश में मेमोरी में वह सब भी शामिल होता है जो संख्यात्मक स्ट्रिंग तर्कों को printf प्लस Hs पर संग्रहीत करने और परिसीमन करने के लिए लेता है । बस के रूप में आप कर सकते हैं:
printf %05000s|tr \ H
... जो 5000 रिक्त स्थान की एक स्ट्रिंग उत्पन्न करता है - जो, कम से कम, आमतौर पर केवल एक बाइट प्रति है और कुछ भी खर्च नहीं करते हैं क्योंकि वे सीमांकित नहीं हैं। कुछ परीक्षणों से संकेत मिलता है कि यहां तक कि कुछ के लिए 5000 बाइट्स कांटा की लागत और trइसके लिए आवश्यक पाइप भी इस मामले में इसके लायक है, और यह लगभग हमेशा होता है जब संख्या अधिक हो जाती है।
मैं भाग गया ...
time bash -c 'printf H%.0s {1..5000}' >/dev/null
...तथा...
time bash -c 'printf %05000s|tr \ H' >/dev/null
प्रत्येक के बारे में 5 बार एक टुकड़ा (यहां कुछ भी नहीं वैज्ञानिक - केवल उपाख्यानात्मक) और ब्रेस विस्तार संस्करण कुल प्रसंस्करण समय में .02 सेकंड से थोड़ा अधिक था, लेकिन trसंस्करण लगभग .012 सेकंड में औसतन आया - और trसंस्करण ने इसे हरा दिया। हर बार। मैं यह नहीं कह सकता कि मैं आश्चर्यचकित हूं - {brace expansion}एक उपयोगी इंटरैक्टिव शेल शॉर्टहैंड फीचर है, लेकिन आमतौर पर यह एक बेकार बात है जहां किसी भी तरह की स्क्रिप्टिंग का संबंध है। सामान्य रूप:
for i in {[num]..[num]}; do ...
... जब आप इसके बारे में सोचते हैं, तो वास्तव में दो for छोरें हैं - पहला आंतरिक है और इसमें निहित है कि शेल को किसी तरह से लूप करना चाहिए ताकि उन सभी को बचाने से पहले उन पुनरावृत्तियों को उत्पन्न किया जा सके और उन्हें आपके forलूप के लिए फिर से पुनरावृत्त किया जा सके । ऐसी चीजें आमतौर पर बेहतर की जाती हैं जैसे:
iterator=$start
until [ "$((iterator+=interval))" -gt "$end" ]; do ...
... क्योंकि आप केवल बहुत कम मूल्यों को संग्रहीत करते हैं और उन्हें अधिलेखित करते हैं जैसे ही आप पुनरावृति करते हैं और पुनरावृति करते समय पुनरावृत्ति करते हैं।
वैसे भी, पहले बताए गए स्थान की गद्दी की तरह, आप printfअंकों की एक मनमानी संख्या को फिर से खोलने के लिए भी उपयोग कर सकते हैं , निश्चित रूप से, जैसे:
printf %05000d
मैं तर्क के बिना दोनों करता हूं क्योंकि printfजब कोई तर्क नहीं मिलता है तो प्रारूप स्ट्रिंग में निर्दिष्ट प्रत्येक तर्क के लिए अशक्त स्ट्रिंग का उपयोग किया जाता है - जिसे एक अंक तर्क के लिए शून्य या स्ट्रिंग के लिए एक रिक्त स्ट्रिंग के रूप में व्याख्या की जाती है।
यह सिक्के का दूसरा (और - मेरी राय में - अधिक कुशल) पक्ष का है जब प्रश्न में आदेश के साथ तुलना की जाती है - जबकि किसी चीज से कुछ भी प्राप्त करना संभव नहीं है जब आप printf %.0प्रत्येक तर्क के लिए लंबाई बढ़ाते हैं, तो यह भी है कुछ नहीं से कुछ प्राप्त करना संभव है।
उत्पन्न बाइट्स की बड़ी मात्रा के लिए अभी भी आप इसका उपयोग कर सकते हैं dd:
printf \\0| dd bs=64k conv=sync
... और w / नियमित फ़ाइलों ddका seek=[num]तर्क अधिक से अधिक लाभ के लिए इस्तेमाल किया जा सकता है। यदि आप ,unblock cbs=1ऊपर से जोड़ते हैं और आप के साथ प्रति पंक्ति मनमाने ढंग से तार इंजेक्षन कर सकते हैं pasteऔर /dev/null- लेकिन उस स्थिति में, यदि यह आपके लिए उपलब्ध है, तो आप उपयोग कर सकते हैं:
yes 'output string forever'
यहाँ कुछ और ddउदाहरण हैं:
dd bs=5000 seek=1 if=/dev/null of=./H.txt
... जो वर्तमान निर्देशिका में एक भरी हुई फ़ाइल बनाता है (या\0NUL आकार 5000 बाइट्स के H.txt नाम की निर्देशिका में ) । ddऑफसेट के लिए सीधे चाहता है और NUL- इसके पीछे सभी को भरता है।
<&1 dd bs=5000 conv=sync,noerror count=1 | tr \\0 H >./H.txt
... जो एक ही नाम और आकार की फ़ाइल बनाता है लेकिन w / H वर्णों को भर देता है। यह ddएक पढ़ने में त्रुटि के मामले में कम से कम एक पूर्ण अशक्त-ब्लॉक लिखने के व्यवहार का लाभ उठाता है जब noerrorऔर syncरूपांतरण निर्दिष्ट किए जाते हैं (और - बिना count=- संभवत: आप जितना चाहते थे उससे अधिक समय तक चलेगा) , और जानबूझकर पुनर्निर्देशन एक लिखित फाइल डिस्क्रिप्टर की स्टडिन पर dd।
tcshयाzsh,repeat 5000 printf Hसमझने के लिए आसान है। इसके साथperl:print "H" x 5000(ध्यान दें कि{1..5000}यह एक zsh ऑपरेटर है जो बाद में ksh93 और bash द्वारा कॉपी किया गया हैperl) से प्रेरित है1..5000