यह मैं आपको सुझाव देता हूं कि आपको इसे कैसे करना चाहिए, और मैं समझाऊंगा कि क्यों, लेकिन पहले मैं कुछ और बात करना चाहता हूं ...
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
यहाँ कई अन्य सॉल्यूशन दिए गए समाधानों से यह प्रतीत होता है कि आप इसे विस्तार करने के अपने तरीकों में बदलाव करके किसी शेल वेरिएबल की सामग्री को प्रभावित कर सकते हैं। मैं आपको आश्वस्त कर सकता हूं कि ऐसा नहीं है।
string="some stuff here \
some more stuff here."
echo $string ${#string}
echo "$string" "${#string}"
आउटपुट
some stuff here some more stuff here. 53
some stuff here some more stuff here. 53
जो आप ऊपर देख रहे हैं वह पहले एक फ़ील्ड-स्प्लिट विस्तार है, फिर विस्तार के स्रोत चर के लिए बाइट-काउंट पर एक रिपोर्ट, फिर एक उद्धरण-सीमांकित विस्तार, और एक ही बाइट-काउंट। जबकि आउटपुट भिन्न हो सकता है शेल चर की सामग्री $string
असाइनमेंट को छोड़कर कभी भी नहीं बदलती है।
क्या अधिक है, अगर आपको समझ नहीं आ रहा है कि यह क्यों है, तो आप बाद में की तुलना में कुछ बहुत ही आश्चर्यजनक आश्चर्य का सामना करने के लिए बाध्य हैं। आइए फिर से कोशिश करें, लेकिन थोड़ा अलग परिस्थितियों में।
IFS=sf
echo $string ${#string}
echo "$string" "${#string}"
समान $string
- अलग वातावरण।
आउटपुट
ome tu here ome more tu here. 53
some stuff here some more stuff here. 53
क्षेत्र में विभाजित क्षेत्र के आधार पर क्षेत्र का विभाजन होता है $IFS
। दो प्रकार के सीमांकक हैं - $IFS
व्हॉट्सएप और $IFS
कुछ भी। डिफ़ॉल्ट $IFS
रूप से मान स्पेस टैब न्यूलाइन को असाइन किया जाता है - जो कि तीन संभावित $IFS
व्हाट्सएप मान हैं। यह आसानी से बदल जाता है, हालांकि, जैसा कि आप ऊपर देख सकते हैं, और क्षेत्र-विभाजन के विस्तार पर भारी प्रभाव पड़ सकता है।
$IFS
व्हॉट्सएप एक एकल क्षेत्र के लिए अनुक्रम से आगे बढ़ेगा - और इस कारण अंतरिक्ष के echo
किसी भी क्रम से युक्त विस्तार का विस्तार $IFS
होता है जब एक अंतरिक्ष में केवल एक ही स्थान का मूल्यांकन होगा - क्योंकि echo
रिक्त स्थान पर अपने तर्कों को व्यक्त करता है। लेकिन कोई भी गैर-व्हाट्सएप मान उसी तरह से खत्म नहीं होगा, और प्रत्येक होने वाला सीमांकक हमेशा अपने आप को एक क्षेत्र प्राप्त करता है - जैसा कि ऊपर के सामान विस्तार में देखा जा सकता है ।
यह इसका सबसे बुरा नहीं है। इस पर विचार करें $string
।
IFS=$space$tab$newline
cd emptydir
string=" * * * \
* * * "
echo $string ${#string}
echo "$string" "${#string}"
आउटपुट
* * * * * * 30
* * * * * * 30
ठीक लग रहा है, है ना? ठीक है, चलो पर्यावरण को फिर से बदल दें।
touch file1 file2 file3 file4 file5
echo $string ${#string}
echo "$string" "${#string}"
आउटपुट
file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 30
* * * * * * 30
ओह।
यदि यह उनसे मेल खा सकता है तो डिफ़ॉल्ट रूप से शेल फाइलनाम ग्लब्स का विस्तार करेगा। यह पैरामीटर विस्तार और उसके पार्स-क्रम में क्षेत्र-विभाजन के बाद होता है और इसलिए किसी भी तरह से बिना तार वाले तार इस तरह से कमजोर होते हैं। set -f
यदि आप चाहें तो इस व्यवहार को बंद कर सकते हैं, लेकिन कोई भी POSIX- संगत शेल हमेशा डिफ़ॉल्ट रूप से गोलाकार होगा।
जब आप अपनी इंडेंटेशन वरीयताओं के अनुरूप विस्तार करने के लिए उद्धरण छोड़ते हैं तो यह उस तरह का सामान होता है, जब आप उसके विरुद्ध होते हैं। और फिर भी, हर मामले में, अपने विस्तार के व्यवहार की परवाह किए बिना, $string
हमेशा के लिए वास्तविक मूल्य अभी भी जो कुछ भी था जब आपने इसे आखिरी बार सौंपा था। तो चलिए पहली बात पर वापस आते हैं।
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
echo "$var" "${#var}"
आउटपुट
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like. 70
मेरा मानना है कि शेल सिंटैक्स को आपकी इंडेंटेशन वरीयताओं के लिए अनुकूलित करने का यह एक बहुत ही अच्छा तरीका है। मैं जो कुछ ऊपर कर रहा हूं, वह प्रत्येक व्यक्ति को एक स्ट्रिंग को एक स्थिति पैरामीटर में निर्दिष्ट कर रहा है - जिसे प्रत्येक को संख्या द्वारा संदर्भित किया जा सकता है जैसे - $1
या ${33}
फिर $var
विशेष शेल पैरामीटर का उपयोग करने के लिए अपने समसामयिक मूल्यों को निर्दिष्ट करना $*
।
यह दृष्टिकोण प्रतिरक्षा नहीं है $IFS
, फिर भी। फिर भी, मैं $IFS
इस संबंध में एक अतिरिक्त लाभ के लिए इसके संबंध पर विचार करता हूं । विचार करें:
IFS=\ ;space_split="$*"
IFS=/; slash_split="$*";IFS='
';new_line_split="$*"
echo "$space_split"
echo "$slash_split"
echo "$new_line_split"
आउटपुट
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like.
Arg 1: Line 1./Arg 2: Line 2./and so on for/as long as you might like.
Arg 1: Line 1.
Arg 2: Line 2.
and so on for
as long as you might like.
जैसा कि आप देख सकते हैं, पहले बाइट पर $*
प्रत्येक arg को अंदर "$@"
करता है $IFS
। इसलिए $IFS
अलग-अलग असाइन किए जाने पर इसके मूल्य को सहेजना प्रत्येक सहेजे गए मूल्य के लिए अलग-अलग क्षेत्र परिसीमन प्राप्त करता है। ऊपर आप जो देख रहे हैं, वह प्रत्येक चर के लिए शाब्दिक मूल्य है। यदि आप चाहते थे कि आप कोई परिसीमन न करें:
IFS=;delimitless="$*"
echo "$delimitless" "${#delimitless}"
आउटपुट
Arg 1: Line 1.Arg 2: Line 2.and so on foras long as you might like. 67