मैं एक स्क्रिप्ट कैसे बना सकता हूं कि वह फाइव्स को गिन सके।


10

मैं 375 और 3500 (375, 380, 385 ...) के बीच पांच के सभी गुणकों को सूचीबद्ध करने के लिए एक बहुत ही सरल बैश स्क्रिप्ट बनाने की कोशिश कर रहा था। एक चीज़ जो मैंने कोशिश की और काम नहीं किया:

for i in {375..3500}
do
        echo $i
        (($i += 5))
done

मैंने कुछ समय बाद हार मान ली और इसे लगभग 15 सेकंड में BASIC में लिखा:

10 count = 375
20 print count
30 count = count+5
40 if count < 3500 then goto 20

मैं अपने बेसिक प्रोग्राम को बैश स्क्रिप्ट में कैसे बना सकता हूं?


यह स्टैक ओवरफ्लो पर बेहतर है - यूनिक्स और लिनक्स ओएस के बारे में है, कोडिंग नहीं। स्टैकओवरफ़्लो के लिए कोडिंग है।
no --zɐɹƆ

जवाबों:


20

वैकल्पिक रूप से लूप के लिए एक पारंपरिक सी-शैली का उपयोग किया जा सकता है:

for ((i=375; i<=3500; i+=5)); do
    echo $i
done

यह शायद seq का उपयोग करने की तुलना में कम स्पष्ट है, लेकिन यह किसी भी उपप्रकार को स्पॉन नहीं करता है। यद्यपि मैं C से परिचित हूं, इसलिए मुझे यह समझने में कोई कठिनाई नहीं होगी, लेकिन YMMV।


1
इस पद्धति का नकारात्मक पक्ष यह है कि यह कम पोर्टेबल है। POSIX श में seq मेथड काम करता है।
राउटर वेरेल्ट

ओह, लूप्स के लिए C- स्टाइल POSIX श में मौजूद नहीं है? आप हर दिन कुछ नया सीखते हैं ...
Muzer

2
अगर आप POSIX श तक सीमित हैं, तो सिवाय इसके कि आप जीयूयू के कोर्यूटिल्स का हिस्सा नहीं हैं। बिजीबॉक्स में अधिक सीमित कार्यान्वयन है, लेकिन इसके बाहर, कई एम्बेडेड सिस्टम की संभावना बिल्कुल भी नहीं होगी।
क्रिस डाउन

1
@ मोजर - कम से कम dashइसका समर्थन नहीं करता। @ क्रिसडाउन - ऐसा कोई कारण नहीं है कि "पोसिक्स श" का अर्थ "कोई सेक् " न हो। लेकिन हाँ, दी गई, मैंने इस तथ्य को नजरअंदाज कर दिया था कि seq POSIX द्वारा निर्दिष्ट नहीं है।
राउटर वेरहेल्ट

27

चूंकि आप वैसे भी ब्रेस विस्तार का उपयोग करते हैं, इसलिए इसकी सुविधा का पूरी तरह से उपयोग करें:

echo {375..3500..5}

तुम भी उपयोग करके वैकल्पिक पाठ के साथ अलग श्रृंखला में प्रत्येक संख्या मुद्रित करने के लिए इस तकनीक का उपयोग कर सकते हैं printfके बजाय echo, उदाहरण के लिए:

$ printf "Number %s is generated.\n" {375..3500..5}
Number 375 is generated.
Number 380 is generated.
Number 385 is generated.
...

संपादित करें

जैसा कि @kojiro द्वारा टिप्पणी में बताया गया है मैक ओएस डिफ़ॉल्ट शेल के रूप में बैश 3 का उपयोग करता है, जो ब्रेस विस्तार के अनुक्रम अभिव्यक्ति में वृद्धि का समर्थन नहीं करता है। आपको संस्करण 4 को bash में अपग्रेड करने या अन्य शेल का उपयोग करने की आवश्यकता है जो इसका समर्थन करता है (उदाहरण के लिए zsh)।


2
यह मैक ओएस 10.10.3 पर मेरे लिए काम नहीं करता है। यह '{375..3500..5}' आउटपुट करता है।
aswine

6
@aswine इसलिए आपको हमेशा पूछते समय अपने ओएस का उल्लेख करना चाहिए । खासकर जब से OSX में अन्य यूनिसेज़ और लिनक्स से दोनों में कई अंतर हैं।
terdon

2
यह प्रति se OS अंतर नहीं है। यह एक संस्करण अंतर है। OS X में केवल BASH 3 OOTB है। आप लगभग किसी भी OS X पैकेज मैनेजर का उपयोग करके इस सदी से BASH इंस्टॉल कर सकते हैं। मैं होम ब्रे का उपयोग करता हूं, एक के लिए।
कोजिरो

2
तथ्य यह है कि विस्तार सीधे विफल रहता है, लेकिन bash -cबहुत अधिक गारंटी में सफल होता है कि दो अलग-अलग गोले शामिल हैं। क्या $SHELL --versionकहते हैं कि यह के बैश 3?
ढग

3
@mikeserv जवाब बहुत ही सरल है - मैंने ऐसा नहीं लिखा क्योंकि मुझे इस बात का कोई अंदाजा नहीं था कि bashइस फीचर को किस संस्करण में पेश किया गया था। मैंने खुद इसे kojiro कमेंट से सीखा है। और कृपया मेरी तुलना SC से न करें, मुझे वास्तव में 1970 के अंत से सभी विवरणों और विवरणों का इतिहास नहीं पता है। एक बार फिर - यदि आप यह उम्मीद करते हैं, तो कृपया नीचे जाएं।
जिमीज जूल 25'15

17

SEQ (1) का उपयोग करना

for i in $(seq 375 5 3500)
do
    echo $i
done

या केवल:

seq 375 5 3500

4
यहां तक ​​कि सरल लूप को गिराना और बस उपयोग करना होगा seq 375 5 3500
दिगंबर

11

आपके लिए दो कारणों से लूप स्निपेट ने काम नहीं किया:

  • (($i += 5))- यहाँ के $iमूल्य में विस्तार किया गया है i। इस प्रकार विस्तार कुछ ऐसा होगा ((375 += 5)), जिसका कोई मतलब नहीं है (एक शाब्दिक संख्या को दूसरे शाब्दिक संख्या में निर्दिष्ट करने का प्रयास)। यह सामान्य रूप से प्राप्त किया जाएगा ((i += 5))( $चर का विस्तार करने के लिए नहीं )
  • {375..3500}पाश की पहली यात्रा से पहले विस्तार किया जाएगा। यह संख्याओं की सूची होगी 375 376 ... 3499 3500। लूप के प्रत्येक पुनरावृत्ति के लिए, iइन नंबरों में से प्रत्येक को एक-एक करके सौंपा जाएगा। इस प्रकार प्रत्येक पुनरावृत्ति की शुरुआत में, iउस सूची में अगले मान को फिर से असाइन किया जाएगा , 1. चरणों में गिना जाता है। ((i += 5))प्रभावी रूप से कुछ भी नहीं करता है - यह 5 से i जोड़ता है, लेकिन फिर मैं बस फिर से शुरू में फिर से असाइन किया गया हूं अगला पुनरावृत्ति

मुझे लगता है कि मुझे for (( ; ; ))उत्तर सबसे अच्छा लगता है , लेकिन यहां आपको सोचने के लिए कुछ विकल्प दिए गए हैं:


चूंकि हम 5 के गुणकों के साथ काम कर रहे हैं, और {a..b..i}विस्तार bash संस्करण 3.2.57 (1) (OS X में) का समर्थन नहीं करता है, तो हम इसके बजाय यह थोड़ा रहस्यमय चीज़ कर सकते हैं:

for i in 375 {38..349}{0,5} 3500; do
    echo $i
done

यह दर्शाता है कि कार्टेशियन उत्पाद बनाने के लिए बैश का उपयोग कैसे किया जा सकता है।


मुझे लगता है कि सामान्य रूप से लूप के लिए यह करने का सबसे सुविधाजनक तरीका है, लेकिन यदि आप रुचि रखते हैं, तो आप थोड़ी देर के लूप (अपने बेसिक के करीब) का उपयोग कर सकते हैं:

count=375
while (( count <= 3500 )); do
    echo $count
    (( count += 5 ))
done

1
@ जिमीज ... कार्टेसियन उत्पाद क्या है? यदि आप चाहें तो टिप्पणी को अस्वीकार कर सकते हैं, और यदि आप मुझे बताएंगे तो मुझे भी परवाह नहीं होगी। मैं उत्सुक हूँ।
चाटुकार

1
@mikeserv आप टिप्पणी को अस्वीकार नहीं कर सकते: en.wikipedia.org/wiki/Cartesian_product
jimmij

@ जिमीज- अगर आप करते हैं तो यह मेरे साथ अभी भी ठीक है।
चाटुकार

@ जिमीज शैतान आप किस बारे में बात कर रहे हैं? कार्टेशियन उत्पाद दो सेटों से तत्वों के हर संभव संयोजन का एक सेट है (जो एक ही सेट हो सकता है या नहीं भी हो सकता है)। अधिक बोलचाल की भाषा में, यह दो चीजों के समूह से सिर्फ "सभी संभव संयोजन" है। मैं केवल एक सेट देखता हूं। यहाँ कार्टेसियन उत्पाद कैसे है?
jpmc26

1
@ jpmc26 आप सही हैं, यह "सभी संभावित संयोजन" हैं, इसलिए दो अक्षों को प्लॉट करने देता है - पहले से 38अब तक के सभी नंबरों को लिखें 349। दूसरे नंबर पर केवल दो नंबर: 0और 5। अब उन सभी संयोजनों का आदेश दिया जोड़े बनाने की सुविधा देता है - आप एक सेट के रूप में उन्हें लिख सकते हैं: {38,0}, {38,5}... {349,5}, या बस अनावश्यक चिह्न निकाल दें {, ,और }और मिलता है ... नई संख्या 380... 3495
jimmij

5

हालांकि, निश्चित रूप से, इसके लिए एक ऐप है ( seq 375 5 3500), कमांडलाइन से ऐसा करने के विभिन्न तरीके हैं। हालांकि सबसे तेज़ और सरल का उपयोग सिर्फ किया जाएगा seq, यहां कुछ अन्य विकल्प दिए गए हैं:

for i in {375..3500}; do [[ (($i % 5)) -eq 0 ]] && echo $i; done

i=370; while [ $i -le 3500 ]; do printf "%s\n" $((i+=5)); done

perl -le '$i=shift;while($i<=$ARGV[0]){print $i; $i+=5; }' 375 3500
perl -le 'map{print $_ + 5} 370..3495'

awk 'BEGIN{ for(i=375;i<=3500;i+=5){print i}}'

नाइट पिक: $(($i % 5))लिखा जा सकता है $((i % 5))
जी-मैन का कहना है कि 'मोनिका'

4

POSIXly:

i=370
while [ 3500 -gt "$i" ]
do    echo "$((i+=5))"
done

... या ...

echo 'for(x=370;x<=3500;x+=5)x' |bc

मुझे पता नहीं क्यों आप इसे किसी अन्य तरीके से करेंगे। छोड़कर, बिल्कुल ...

seq 375 5 3500

... या इसके साथ dc:

echo '370[5+pd3500>p]splpx'|dc

मैं उत्सुक हूं कि dcकोड कैसे काम करता है। यह निश्चित रूप से उपयोग करने से अधिक पेचीदा है seq
ढग

1
@ ढग - यह थोड़ा लूप लिखता है। यह saves [स्ट्रिंग ]के शीर्ष करने के pसरणी, तो lइसे वापस oads ढेर और ई के शीर्ष पर xमैक्रो के रूप में ecutes यह। मैक्रो के भीतर हम 5स्टैक पर धक्का देते हैं और फिर इसे पॉप करते हैं और ऊपर से दूसरा +, दोनों स्टैक वैल्यू को उनकी राशि से बदल देते हैं, जो पहले से रंटेड pऔर dअपसाइड 3500किया जाता है स्टैक पर धकेल दिया जाता है, जब हम इसे पॉप करते हैं और डुबकी हम बस के लिए बनाते हैं तुलना >। यदि 3500अधिक है, तो हम pसरणी (हमारे वर्तमान मैक्रो) में संग्रहीत स्ट्रिंग को मैक्रो के रूप में लोड और निष्पादित करते हैं , या यदि नहीं तोड़ते हैं।
15

3

यदि आप बैश 3 पर फंस गए हैं:

echo {375..3500} | tr ' ' '\n' | sed -n 'p;n;n;n;n'

और यदि आप पसंद करते हैं awk:

echo {375..3500} | tr ' ' '\n' | awk '!((NR-1)%5)'

मैं ब्रेस विस्तार के बारे में नहीं जानता था - जो कि बहुत अच्छा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.