रिक्त स्थान और वाइल्डकार्ड वाले पथ के साथ स्क्रिप्ट त्रुटि त्रुटि


25

मुझे नीचे बैश स्क्रिप्टिंग की मूल बातें प्राप्त करने में परेशानी हो रही है। यहाँ मेरे पास अभी तक क्या है:

#!/bin/bash
FILES="/home/john/my directory/*.txt"

for f in "${FILES}"
do
  echo "${f}"
done

मैं केवल इतना करना चाहता हूं कि सभी .txtफाइलों को एक forलूप में सूचीबद्ध किया जाए ताकि मैं उनके साथ सामान कर सकूं। लेकिन अभी my directoryऔर तारांकन में जगह *.txtअच्छी तरह से नहीं खेल रहे हैं। मैंने चर नामों पर घुंघराले ब्रेसिज़ के साथ और बिना दोहरे उद्धरणों के साथ और इसके बिना इसका उपयोग करने की कोशिश की, फिर भी सभी .txtफाइलों को प्रिंट नहीं कर सकता ।

यह एक बहुत ही बुनियादी बात है, लेकिन मैं अभी भी संघर्ष कर रहा हूं क्योंकि मैं थका हुआ हूं और सीधे नहीं सोच सकता।

मैं क्या गलत कर रहा हूं?

मैं ऊपर दी गई स्क्रिप्ट को सफलतापूर्वक लागू करने में सक्षम हूं यदि मेरे FILES में कोई स्थान या तारांकन नहीं है ... मुझे काम करने के लिए इसे प्राप्त करने के लिए दोहरे उद्धरणों और ब्रेसिज़ के उपयोग के साथ या बिना प्रयोग करना पड़ा। लेकिन जिस क्षण मेरे पास रिक्त स्थान और तारांकन दोनों हैं, यह सब कुछ गड़बड़ कर देता है।

जवाबों:


33

उद्धरण के अंदर, *फ़ाइलों की सूची में विस्तार नहीं होगा। इस तरह के वाइल्डकार्ड का सफलतापूर्वक उपयोग करने के लिए, यह उद्धरण के बाहर होना चाहिए।

यहां तक ​​कि अगर वाइल्डकार्ड का विस्तार हुआ, तो अभिव्यक्ति "${FILES}"एकल स्ट्रिंग में होगी, न कि फाइलों की सूची में।

एक दृष्टिकोण जो काम करेगा:

#!/bin/bash
DIR="/home/john/my directory/"
for f in "$DIR"/*.txt
do
  echo "${f}"
done

उपरोक्त में, रिक्त स्थान या अन्य कठिन वर्णों वाले फ़ाइल नाम सही ढंग से संभाले जाएंगे।

अधिक उन्नत दृष्टिकोण बैश सरणियों का उपयोग कर सकता है:

#!/bin/bash
FILES=("/home/john/my directory/"*.txt)
for f in "${FILES[@]}"
do
  echo "${f}"
done

इस मामले में, FILESफ़ाइल नामों की एक सरणी है। परिभाषा के इर्द-गिर्द बने परिंदे इसे एक सरणी बनाते हैं। ध्यान दें कि *उद्धरणों के बाहर है। निर्माण "${FILES[@]}"एक विशेष मामला है: यह स्ट्रिंग्स की एक सूची तक विस्तारित होगा जहां प्रत्येक स्ट्रिंग फ़ाइल नामों में से एक है। रिक्त स्थान या अन्य कठिन पात्रों के साथ फ़ाइल नाम सही तरीके से संभाला जाएगा।


1
महान है कि काम किया
जॉन

यह ध्यान देने योग्य है कि यदि आप फ़ंक्शंस के माध्यम से इस तरह के मार्ग से गुजर रहे हैं, तो आपको यह सुनिश्चित करने की आवश्यकता है कि आप चर को एक बड़े स्ट्रिंग के भाग के रूप में for f in "$DIR"/*.txtfor f in "$DIR/*.txt"
समझने के

7

जॉन 1024 द्वारा दिखाए गए सरणियों का उपयोग करते समय, बहुत अधिक समझ में आता है, यहां, आप विभाजन + ग्लोब ऑपरेटर (एक स्केलर वैरिएबल को छोड़कर) का उपयोग भी कर सकते हैं।

चूँकि आप केवल उस ऑपरेटर के गोलाकार भाग को चाहते हैं, आपको विभाजन वाले हिस्से को निष्क्रिय करना होगा :

#! /bin/sh -
# that also works in any sh, so you don't even need to have or use bash

file_pattern="/home/john/my directory/*.txt"
# all uppercase variables should be reserved for environment variables

IFS='' # disable splitting

for f in $file_pattern # here we're not quoting the variable so
                       # we're invoking the split+glob operator.
do
  printf '%s\n' "$f" # avoid the non-reliable, non-portable "echo"
done

0

आप जो कर सकते हैं वह केवल वाइल्डकार्ड वर्णों को उद्धरणों के बाहर छोड़ना है।
की तरह कुछ:
"रिक्त स्थान के साथ फ़ाइलें" में एक के लिए * "। Txt"
करते
प्रसंस्करण
किया
वाइल्डकार्ड खुद को रिक्तियों तक विस्तृत है, तो आप टी लाइन दृष्टिकोण प्रति एक फ़ाइल का उपयोग, उपयोग ls तरह की सूची बनाने के लिए एल की आवश्यकता होगी फ़ाइलों और उपयोग बैश प्रत्येक फ़ाइल प्राप्त करने के लिए पढ़ा।


-1

जब आप फ़ाइलों के सेट पर प्रक्रिया करना चाहते हैं, तो आप विचार करते हैं, उनके नाम पर स्थान हो सकता है या अन्य स्कैप कोड हो सकते हैं, इसलिए अपनी प्रक्रिया शुरू करने से पहले जैसे : for loopया find commandसेट करें IFS bash env variable:

IFS=$(echo -en "\n\b")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.