मैं इस थ्रेड को पढ़ रहा था: किसी फाइल की तर्ज पर लूप कैसे करें?
क्या है IFS? और for-लूप के संदर्भ में इसका क्या उपयोग है ?
मैं इस थ्रेड को पढ़ रहा था: किसी फाइल की तर्ज पर लूप कैसे करें?
क्या है IFS? और for-लूप के संदर्भ में इसका क्या उपयोग है ?
जवाबों:
IFSखड़ा है - यह एक ऐसा चरित्र है जो खेतों को अलग करता है। आपके द्वारा पोस्ट किए गए उदाहरण में, यह नई पंक्ति वर्ण ( ) पर सेट है ; इसलिए आप इसे सेट करने के बाद, टेक्स्ट लाइन को लाइन से प्रोसेस करेंगे। उस उदाहरण में, आप (अपने इनपुट फ़ाइल में आपके पास मौजूद कुछ पत्र के मूल्य) को बदल सकते हैं और जांच सकते हैं कि पाठ कैसे विभाजित होगा।InputInternal Field Separator\nforIFS
BTW, जवाब से आप दूसरा समाधान पोस्ट किया है कि सिफारिश की है ...
के रूप में @jasonwryan देखा, यह नहीं है Inputलेकिन Internal। नाम Inputआया था से awkहै, जिसमें वहाँ भी OFS- Output Field Separator।
S लिए यह कहाँ से उत्पन्न हुआ था। कॉर्न शेल और अधिकांश अन्य बॉर्न-जैसे शेल में जो अब तक निर्दिष्ट किया गया है, डेलिमिटर के लिए है (बस अपनी कल्पना को थोड़ा सा बढ़ाएं) उदाहरण के लिए "ए", "" और "बी" में विभाजित किया गया है (कोई अतिरिक्त नहीं "")। यह 's या पैरामीटर विस्तार ध्वज से भिन्न है । POSIXSA::B:awkFSszsh
IFSसीधे लूपिंग से संबंधित नहीं है, यह शब्द विभाजन से संबंधित है। IFSअप्रत्यक्ष रूप से यह निर्धारित करता है कि कमांड से आउटपुट कैसे टुकड़ों में टूट जाता है जो लूप से अधिक हो जाता है।
जब आपके पास एक असुरक्षित चर प्रतिस्थापन $fooया कमांड प्रतिस्थापन होता है $(foo), तो दो मामले होते हैं:
"$foo", या एक चर असाइनमेंट में होता है x=$foo, तो प्रतिस्थापन से उत्पन्न स्ट्रिंग का उपयोग इस प्रकार किया जाता है।$IFSहै उसे शब्द विभाजक माना जाता है। उदाहरण के लिए IFS=":"; foo="12:34::78"; echo $fooप्रिंट 12 34 78(दो रिक्त स्थान के बीच 34और 78, चूंकि एक खाली शब्द है)।foo="*"; echo $fooवर्तमान निर्देशिका में फ़ाइलों की सूची प्रिंट करता है।लूप्स के लिए, कई अन्य संदर्भों की तरह, शब्दों की सूची की अपेक्षा करें। इसलिए
for x in $(foo); do …
$(foo)शब्दों में टूट जाता है, और प्रत्येक शब्द को एक ग्लोब पैटर्न के रूप में मानता है। का डिफ़ॉल्ट मान IFSहै अंतरिक्ष, टैब और न्यू लाइन है, इसलिए यदि fooदो पंक्तियों बाहर प्रिंट hello worldऔर howdyफिर पाश शरीर के साथ क्रियान्वित किया जाता है x=hello, तो x=worldऔर x=howdy। यदि IFSस्पष्ट रूप से केवल एक नई रेखा को बदलने के लिए बदल दिया जाता है, तो लूप को निष्पादित किया जाता है hello worldऔर howdy। तो IFSहोना करने के लिए बदल गया है o, तो पाश के लिए मार डाला है hell, w, rldh(जहां एक नई पंक्ति चरित्र है) और wdy।
"IFS indirectly determines how ..."?
IFS(सीधे) यह निर्धारित करता है कि कमांड प्रतिस्थापन का आउटपुट कैसे टूट गया है, जो तब (अप्रत्यक्ष रूप से) निर्धारित करता है कि लूप क्या खत्म हो गया है।
से man bash
IFS आंतरिक क्षेत्र विभाजक जिसका उपयोग विस्तार के बाद शब्द विभाजन के लिए किया जाता है और रीड बिलिन कमांड के साथ लाइनों को शब्दों में विभाजित किया जाता है। डिफ़ॉल्ट मान "<space> <टैब> <newline>" है।
यह बैश के आंतरिक चर में से एक है। यह निर्धारित करता है कि बैश खेतों, या शब्द सीमाओं को कैसे पहचानता है, जब यह चरित्र के तार की व्याख्या करता है।
हालांकि यह व्हाट्सएप (स्पेस, टैब और न्यूलाइन) को डिफॉल्ट करता है, इसलिए इसे परिवर्तित किया जा सकता है, उदाहरण के लिए, अल्पविराम से अलग की गई डेटा फ़ाइल को पार्स करने के लिए।
पिछले महान उत्तरों के अलावा, मुझे सिर्फ यह जोड़ना है कि IFS सेट के साथ सरल मामलों में कुशल और पोर्टेबल पार्सिंग के लिए बहुत उपयोगी है । कुशल, क्योंकि grep या sed जैसे उप-भाग और स्पॉइंग टूल के उपयोग से बचा जाता है:
resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
xxIFS=$IFS
IFS='x'
set -- $res
width=$1
height=$2
# handle width and height
IFS=$xxIFS
done;
IFS=$xIFS
बस ध्यान दें कि हमें स्क्रिप्ट के अन्य भागों में अवांछित टूटने से बचने के लिए IFS के पिछले मूल्य को संग्रहीत और पुनर्प्राप्त करने की आवश्यकता है ।