2017-04-01 9 views
6

पर सेट है, मैं एक बैश tutorial, और विशेष रूप से शब्द विभाजन के विषय में जा रहा हूं।आईएफएस के साथ बैश में वर्ड स्प्लिटिंग एक गैर-व्हाइटस्पेस कैरेक्टर

$ ./args hello world, here is "a string of text!" 
5 args: <hello> <world,> <here> <is> <a string of text!> 

अब तक तो अच्छा:

यह स्क्रिप्ट, बुलाया "आर्ग", शब्द बंटवारे उदाहरण

#!/usr/bin/env bash 
printf "%d args:" $# 
printf " <%s>" "[email protected]" 
echo 

एक उदाहरण प्रदर्शित मदद करता है। मैं समझता हूं कि यह कैसे काम करता है।

हालांकि, जब मैं एक गैर-व्हाइटस्पेस चरित्र के साथ आईएफएस को प्रतिस्थापित करता हूं, तो ":" कहें, यदि स्क्रिप्ट सीधे तर्क के रूप में पास करता है तो स्क्रिप्ट शब्द विभाजन नहीं करती है।

$ ./args one:two:three 
1 args: <one:two:three> 

हालांकि, स्क्रिप्ट एक ही स्ट्रिंग के लिए शब्द बंटवारे प्रदर्शन करता है, तो मैं (1) एक चर करने के लिए स्ट्रिंग असाइन करें, और उसके बाद (2) पैरामीटर विस्तार के माध्यम से स्क्रिप्ट को स्ट्रिंग पारित करता है।

$ IFS=: 
$ variable="one:two:three" 
$ ./args $variable 
3 args: <one> <two> <three> 

क्यों? विशेष रूप से, स्ट्रिंग को एक तर्क के रूप में गुजरने से शब्द विभाजन से गुजरता है जब आईएफएस अनसेट होता है और डिलीमीटर व्हाइटस्पेस वर्ण होते हैं, लेकिन जब आईएफएस गैर-व्हाइटस्पेस वर्णों पर सेट नहीं होता है?

जब मैं इस स्क्रिप्ट के बजाय read का उपयोग करता हूं, वही स्ट्रिंग भी शब्द विभाजन को अपेक्षित रूप से गुजरती है।

$ IFS=: 
$ read a b c 
one:two:three 
$ echo $a $b $c 
one two three 

उत्तर

9

शानदार सवाल! आप शब्द विभाजन here के बारे में और अधिक पढ़ सकते हैं।

खोल पैरामीटर विस्तार, आदेश प्रतिस्थापन, और गणित विस्तार है कि शब्द बंटवारे के लिए दोहरे उद्धरण चिह्नों के भीतर नहीं होती है के परिणामों को स्कैन करता है। क्योंकि नंगे स्ट्रिंग नहीं पैरामीटर विस्तार, आदेश प्रतिस्थापन, या अंकगणितीय विस्तार संदर्भों में से एक है

जब आप आईएफएस : करने के लिए सेट के साथ एक तर्क के रूप नंगे स्ट्रिंग one:two:three गुजरती हैं, बैश शब्द बंटवारे नहीं करता है।

हालांकि, जब एक ही स्ट्रिंग को एक चर के लिए आवंटित किया जाता है और चर को स्क्रिप्ट पर छोड़ा जाता है, तो शब्द विभाजन होता है क्योंकि यह पैरामीटर विस्तार का मामला होता है।

एक ही बात इन के रूप में अच्छी तरह से (आदेश प्रतिस्थापन) पर लागू होता है:

$ ./args $(echo one:two:three) 
3 args: <one> <two> <three> 

$ ./args "$(echo one:two:three)" 
1 args: <one:two:three> 

documented के रूप में, read आदेश, हर पंक्ति पढ़ने पर शब्द बंटवारे करते जब तक कि भारतीय विदेश सेवा रिक्त स्ट्रिंग पर स्थापित किया गया है है।


+1

अच्छा काम किया, आप किसी न किसी कि एक ':)' –

+0

मैं समझता हूँ के रूप में खोल विस्तार के आदेश के नियमों के अनुसार gnu.org में विस्तृत पैरामीटर विस्तार, शब्द बंटवारे के बाद किया जाएगा। इसके अलावा, आपने मुझे भेजे गए पहले लिंक में, आखिरी पंक्ति पढ़ती है "ध्यान दें कि यदि कोई विस्तार नहीं होता है, तो कोई विभाजन नहीं किया जाता है।" समझ गया। तो फिर जब मैं निष्पादित करता हूं तो इस स्क्रिप्ट में _is_ शब्द विभाजन क्यों ट्रिगर हुआ।/ हैलो दुनिया का तर्क है, यहां "पाठ की एक स्ट्रिंग है!" '? मैंने स्पष्ट रूप से पैरामीटर विस्तार नहीं किया है, फिर भी शब्द विभाजन का प्रदर्शन किया जाता है, जिसका अर्थ है कि कुछ विस्तार हुआ है। –

+1

केवल एक चीज जो मैं देख रहा हूं वह यह है कि डिफ़ॉल्ट व्हाइटस्पेस वर्णों पर सेट आईएफएस के साथ एक नंगे स्ट्रिंग शब्द विभाजन को ट्रिगर करती है, लेकिन गैर-व्हाइटस्पेस वर्ण में सेट आईएफएस के साथ एक नंगे स्ट्रिंग तब तक नहीं होती है जब तक इसे पैरामीटर विस्तार से स्पष्ट रूप से नहीं कहा जाता है, कमांड प्रतिस्थापन या समान विस्तार। मेरा अनुमान है कि इसे printf buildin के साथ और अधिक करना है, और _that_ कैसे काम करता है इस पर समझ की कमी है। आपने मूल रूप से उतना ही कहा था जब आपने कहा था "दस्तावेज के रूप में, 'read' कमांड प्रत्येक पंक्ति को पढ़ने पर शब्द विभाजित करता है, जब तक कि आईएफएस को खाली स्ट्रिंग पर सेट नहीं किया जाता है। लगता है कि printf चीजों को अलग करता है। –

संबंधित मुद्दे