एक बैश शेल स्क्रिप्ट में, लूप के लिए लिखना जो स्ट्रिंग मानों पर आधारित है


24

बैश में, मुझे पता है कि एक forलूप लिखना संभव है जिसमें कुछ लूप नियंत्रण चर iपूर्णांक पर निर्दिष्ट करता है। उदाहरण के लिए, मैं एक बैश शेल स्क्रिप्ट लिख सकता हूं जो 1 और 10 के बीच पूर्णांक को प्रिंट करता है:

#!/bin/bash

for i in {1..10}
do
 echo $i
done

क्या लूप नियंत्रण चर पर स्ट्रिंग करने के बजाय पुनरावृति संभव है, यदि मैं स्ट्रिंग की सूची प्रदान करता हूं? उदाहरण के लिए, मान लें कि मेरे पास एक स्ट्रिंग है fnameजो फ़ाइल नाम का प्रतिनिधित्व करता है। मैं प्रत्येक फ़ाइल नाम के लिए कमांड के एक सेट को कॉल करना चाहता हूं। उदाहरण के लिए, मैं fnameइस तरह से एक कमांड का उपयोग करने की सामग्री प्रिंट करना चाह सकता हूं :

#!/bin/bash

for fname in {"a.txt", "b.txt", "c.txt"}
do
 echo $fname
done

दूसरे शब्दों में, पहली पुनरावृत्ति पर, fnameमान होना चाहिए fname="a.txt", जबकि दूसरी पुनरावृत्ति पर, fnameमान होना चाहिए fname="b.txt", और इसी तरह। दुर्भाग्य से, ऐसा लगता है कि उपरोक्त वाक्यविन्यास काफी सही नहीं है। मैं आउटपुट प्राप्त करना चाहूंगा:

a.txt

b.txt

c.txt

लेकिन जब मैं उपरोक्त कोड की कोशिश करता हूं, तो मुझे यह आउटपुट प्राप्त होता है:

{A.txt,

b.txt,

c.txt}

क्या आप मुझे सही सिंटैक्स निर्धारित करने में मदद कर सकते हैं, ताकि मैं चर के मान / सामग्री को परिवर्तित कर सकूं fname? आपके समय के लिए शुक्रिया।


5
निकालें {}, आपको (स्पेस-सीमांकित) सूची पर लूप के लिए कुछ भी करने की आवश्यकता नहीं है
Mat

3
साधन @Mat हटाने {} और, रों। विकल्प रिक्त स्थान को हटाने के लिए है। तो या तो "a.txt" "b.txt" "c.txt"या {"a.txt","b.txt","c.txt"}। लेकिन मैं {a..c}.txtइसके बजाय पसंद करते हैं।
मैनटवर्क

जवाबों:


39

सही सिंटैक्स निम्नानुसार है:

#!/bin/bash

for fname in a.txt b.txt c.txt
do
  echo $fname
done

9
इसके अलावा, नामों की एक सरणी मानकर fnames=( a.txt b.txt c.txt )आप वाक्यविन्यास का उपयोग कर सकते हैं for f in ${fnames[@]}; do echo $f; done

1
क्या यह सच है कि for fname in a.txt b.txt c.txtऔर for fname in "a.txt" "b.txt" "c.txt"समान परिणाम प्राप्त करें?
एंड्रयू

एंड्रयू, हाँ यह सच है। वे समान परिणाम देंगे
अली गंगजी

1
यदि मूल्यों में व्हॉट्सएप हो सकता है , तो बेशक आपको for f in "${fnames[@]}"; do echo $f; done(उद्धरणों के साथ ${fnames[@]}) का उपयोग करना चाहिए fnames। और आपको उपयोग करना चाहिए "$f", खासकर यदि आप कुछ भी अधिक परिष्कृत कर रहे हैं echo(जैसे, catया cp)। (और यहां तक ​​कि अगर आप केवल कर रहे हैं echo, तो आपको printfइसके बजाय उपयोग करना चाहिए ।)
स्कॉट

मुझे लगता है कि @ user13742 को उत्तर में भी ध्यान दिया जाना चाहिए।
फॉलेंप्रिपर

1

लगता है तुम मुझे बस करना चाहिए ...

printf %s.txt\\n a b c

मुझे यह पसंद है, भले ही ओपी की संभावना मन में कुछ करने के अलावा अन्य गूंज से पहले थी।
एल्डर गीक

0

में user13742 द्वारा बताया गया है टिप्पणी , हम में सरणियों का उपयोग कर सकते bashहैं और ksh:

#!/usr/bin/env bash

files_list=( "a.txt" "b.txt" "c and space.txt" )

for i in "${files_list[@]}"
do
    echo "$i"
    # do something else here,maybe
done

और काम करता है:

$ ./iterate_files_array.sh                                                      
a.txt
b.txt
c and space.txt

हालाँकि, कुछ गोले dash( जैसे /bin/shउबंटू पर) सरणियों का समर्थन नहीं करते हैं। ऐसे मामले में हम यहाँ दस्तावेज़ संरचना का उपयोग कर सकते हैं:<<

#!/bin/sh

while IFS= read -r line
do
    echo "$line"
done << EOL
one.txt
two.txt
with space.txt
EOL
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.