मैं बैश में लूप के लिए कैसे लिखूं


93

मैं बुनियादी पाश की तलाश कर रहा हूँ जैसे:

for(int i = 0; i < MAX; i++) {
  doSomething(i);
}

लेकिन मार के लिए।


जवाबों:


103

से इस साइट :

for i in $(seq 1 10);
do
    echo $i
done

10
यह एक उल्लेख के लायक है कि यहां निर्दिष्ट सीमा समावेशी है । उसके द्वारा, मेरा मतलब है कि आप पूरी रेंज (1 से 10) कंसोल पर प्रिंट होते देखेंगे।
जेमी


34

बैश forमें एक चर (पुनरावृत्त) और शब्दों की एक सूची होती है, जहां पुनरावृत्त अच्छी तरह से, पुनरावृति करेगा।

इसलिए, यदि आपके पास शब्दों की एक सीमित सूची है, तो बस उन्हें निम्नलिखित सिंटैक्स में रखें:

for w in word1 word2 word3
do
  doSomething($w)
done

संभवतः आप कुछ संख्याओं के साथ पुनरावृति करना चाहते हैं, इसलिए आप अपने लिए seqसंख्याओं की सूची बनाने के लिए कमांड का उपयोग कर सकते हैं : (उदाहरण के लिए 1 से 100 तक)

seq 1 100

और इसे लूप में उपयोग करें:

for n in $(seq 1 100)
do
  doSomething($n)
done

$(...)वाक्यविन्यास पर ध्यान दें । यह एक बैश व्यवहार है, यह आप एक आदेश से निर्गम (से हमारे मामले में पारित करने के लिए अनुमति देता है seqदूसरे के लिए) ( for)

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

for d in $(find $somepath -type d)
do
  doSomething($d)
done

सूचियाँ उत्पन्न करने के लिए संभावनाएँ अनंत हैं।


2
अच्छा उत्तर, लेकिन आप इसमें (i = 0; i <MAX; i ++) शामिल करना चाहते हैं; doSomething ($ i); वैरिएंट भी किया। मुझे लगता है कि यह आम तौर पर $ i (seq 0 MAX) वेरिएंट के लिए पसंद किया जाता है क्योंकि बाद में पहले लूप निष्पादित करने से पहले 0 से अधिकतम तक सभी नंबर उत्पन्न होंगे।
स्वेच्छा से

30

बैश 3.0+ इस सिंटैक्स का उपयोग कर सकते हैं:

for i in {1..10} ; do ... ; done

.. जो अनुक्रम (जैसे seq 1 10) का विस्तार करने के लिए एक बाहरी कार्यक्रम को जन्म देने से बचता है ।

बेशक, यह for(())समाधान के रूप में एक ही समस्या है , बैश और यहां तक ​​कि एक विशेष संस्करण से बंधा हुआ है (यदि यह आपके लिए मायने रखता है)।


14

bashअंतर्निहित मदद का प्रयास करें :


$ help for

for: for NAME [in WORDS ... ;] do COMMANDS; done
    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
    Equivalent to
        (( EXP1 ))
        while (( EXP2 )); do
            COMMANDS
            (( EXP3 ))
        done
    EXP1, EXP2, and EXP3 are arithmetic expressions.  If any expression is
    omitted, it behaves as if it evaluates to 1.



5
#! /bin/bash

function do_something {
   echo value=${1}
}

MAX=4
for (( i=0; i<MAX; i++ )) ; {
   do_something ${i}
}

यहाँ एक उदाहरण है जो पुराने गोले में भी काम कर सकता है, जबकि अभी भी बड़ी गिनती के लिए कुशल है:

Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'

लेकिन सौभाग्य अंदर उपयोगी चीजें कर रहा हैawk : मैं एक अजीब स्क्रिप्ट में शेल चर का उपयोग कैसे करूं?


2
मैंने पहले इसे नोटिस नहीं किया था, लेकिन एक समान वाक्यविन्यास पहले के उत्तरों में से एक में दिखाया गया है। यहाँ विशिष्ट बात यह है कि ठेठ do/ doneजोड़ी के बजाय घुंघराले ब्रेसिज़ का उपयोग किया जाता है ।
ब्रेंट बर्नबर्न

4

मैं आमतौर पर लूप के लिए मानक पर एक मामूली संस्करण का उपयोग करना पसंद करता हूं। मैं अक्सर दूरस्थ मेजबानों की एक श्रृंखला पर कमांड चलाने के लिए इसका उपयोग करता हूं। मैं लूप के निर्माण के लिए बैश के ब्रेस विस्तार का लाभ उठाता हूं जिससे मुझे गैर-संख्यात्मक लूप बनाने की अनुमति मिलती है।

उदाहरण:

मैं फ्रंटएंड मेजबानों पर अपटाइम कमांड 1-5 से चलाना चाहता हूं और मेजबानों को 1-3 से पीछे करना चाहता हूं:

% for host in {frontend{1..5},backend{1..3}}.mycompany.com
    do ssh $host "echo -n $host; uptime"
  done

मैं आमतौर पर ऊपर के अधिक पठनीय संस्करण के बजाय लाइनों के सिरों पर अर्धविराम के साथ एकल-पंक्ति कमांड के रूप में इसे चलाता हूं। प्रमुख उपयोग विचार यह है कि ब्रेसिज़ आपको कई मूल्यों को एक स्ट्रिंग में डालने की अनुमति देता है (जैसे पूर्व {foo, bar} पोस्ट परिणाम prefoopost, prebarpost में) और डबल अवधि (आप उपयोग कर सकते हैं) का उपयोग करके गिनती / अनुक्रम की अनुमति देते हैं। .ज आदि)। हालाँकि, डबल पीरियड सिंटैक्स bash 3.0 की एक नई विशेषता है; पुराने संस्करण इसका समर्थन नहीं करेंगे।


इससे संबंधित, क्या होगा यदि $ host var किसी दुर्घटना से खाली रेखा है? यह अभी भी ssh आग होगा। तो, मैं इससे कैसे बचूं? मेरे मामले में मैं कुछ अलग कर रहा हूं और इसलिए आपका जवाब मुझे मदद करेगा। मैं नए संदेशों के लिए जीमेल की जाँच करने की कोशिश कर रहा हूँ, और यदि मिल भी जाए तो और विषय का एसएमएस भेजें। यदि आप इसे पढ़ना चाहते हैं, तो मेरा प्रश्न "कनेक्टिंग टू बैश कमांड्स" है।
वोलोमाइक

मुझे विश्वास नहीं है कि आपको एक खाली $ होस्ट संस्करण मिलेगा। ऐसा इसलिए है क्योंकि ऊपर का उदाहरण ब्रेस विस्तार का उपयोग कर रहा है। लूप के लिए स्पष्ट रूप से $ होस्ट चर को मूल्यों पर सेट करता है: frontend1.mycompany.com frontend2.mycompany.com। । backend1.mycompany.com लेकिन अगर आपको इसके लिए एक शून्य मूल्य दिखाई देता है; मैं जानना चाहूंगा। आप सशर्त परीक्षण के अंदर ssh निष्पादित कर सकते हैं यदि यह एक चिंता का विषय था।
19

1

यदि आप केवल "के लिए (...))" को प्रस्तुत करते हैं, तो ऊपर प्रस्तुत समाधान को रोकना सबसे अच्छा है, लेकिन अगर आप ऐसा कुछ चाहते हैं जो SH SHI के अनुरूप हो, जो सभी यूनियनों पर काम करेगा, तो आपको "expr" और का उपयोग करना होगा "जबकि", और ऐसा इसलिए है क्योंकि "())" या "seq" या "i = i + 1" वे विभिन्न गोले के लिए पोर्टेबल नहीं हैं


0

मैं फ़ाइलों को संसाधित करने के लिए हर समय इसके विभिन्न रूपों का उपयोग करता हूं ...

फ़ाइलों के लिए * .log में; गूंज "करो सामान के साथ: $ फाइलें"; गूंज "अधिक सामान के साथ: $ फाइलें"; किया हुआ;

यदि फ़ाइलों की प्रसंस्करण सूची में आप क्या रुचि रखते हैं, फ़ाइलों के लिए -execdir विकल्प देखें ।


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