मेरे पास एक बैश शेल स्क्रिप्ट है जो एक निश्चित डायरेक्टरी के सभी चाइल्ड डायरेक्टरीज़ (लेकिन फाइल नहीं) के माध्यम से लूप करती है। समस्या यह है कि कुछ निर्देशिका नामों में रिक्त स्थान होते हैं।
यहाँ मेरे परीक्षण निर्देशिका की सामग्री हैं:
$ls -F test
Baltimore/ Cherry Hill/ Edison/ New York City/ Philadelphia/ cities.txt
और कोड जो निर्देशिकाओं के माध्यम से लूप करता है:
for f in `find test/* -type d`; do
echo $f
done
यहाँ उत्पादन है:
परीक्षा / बाल्टीमोर परीक्षा / चेरी पहाड़ी परीक्षा / एडीसन परीक्षण / नई यॉर्क Faridabad परीक्षा / फिलाडेल्फिया
चेरी हिल और न्यूयॉर्क शहर को 2 या 3 अलग प्रविष्टियों के रूप में माना जाता है।
मैंने फिल्म के नामों को उद्धृत करने की कोशिश की, जैसे:
for f in `find test/* -type d | sed -e 's/^/\"/' | sed -e 's/$/\"/'`; do
echo $f
done
लेकिन कोई फायदा नहीं हुआ।
ऐसा करने का एक सरल तरीका है।
नीचे दिए गए जवाब बहुत अच्छे हैं। लेकिन इसे और अधिक जटिल बनाने के लिए - मैं हमेशा अपने परीक्षण निर्देशिका में सूचीबद्ध निर्देशिकाओं का उपयोग नहीं करना चाहता। कभी-कभी मैं निर्देशिका नामों को इसके बजाय कमांड-लाइन मापदंडों के रूप में पारित करना चाहता हूं।
IFS को स्थापित करने के लिए मैंने चार्ल्स का सुझाव लिया और निम्नलिखित बातों के साथ आया:
dirlist="${@}"
(
[[ -z "$dirlist" ]] && dirlist=`find test -mindepth 1 -type d` && IFS=$'\n'
for d in $dirlist; do
echo $d
done
)
और यह ठीक काम करता है जब तक कि कमांड लाइन के तर्कों में स्थान नहीं हैं (भले ही उन तर्कों को उद्धृत किया गया हो)। उदाहरण के लिए, इस तरह से स्क्रिप्ट को कॉल करना: test.sh "Cherry Hill" "New York City"
निम्नलिखित आउटपुट उत्पन्न करता है:
चेरी पहाड़ी नया यॉर्क Faridabad
list="$@"
मूल मान सूची-नेस को पूरी तरह से अलग करता है, इसे एक स्ट्रिंग में ढहता है। कृपया मेरे उत्तर में दिए गए निर्देशों का पालन करें - इस तरह के असाइनमेंट को उसमें कहीं भी प्रोत्साहित नहीं किया जाता है; यदि आप किसी प्रोग्राम में कमांड-लाइन तर्कों की एक सूची पास करना चाहते हैं, तो आपको उन्हें एक सरणी में इकट्ठा करना चाहिए, और उस सरणी को सीधे विस्तारित करना चाहिए।