बैश शेल स्क्रिप्ट की शुरुआत में निम्नलिखित पंक्ति है:
IFS=$'\n'
प्रतीकों के इस संग्रह के पीछे का अर्थ क्या है?
IFS=$'\n'बशीवाद है (+ अन्य गोले, ANSI-C उद्धरण का उपयोग करें , वर्कअराउंड के लिए stackoverflow.com/questions/10748703/…
बैश शेल स्क्रिप्ट की शुरुआत में निम्नलिखित पंक्ति है:
IFS=$'\n'
प्रतीकों के इस संग्रह के पीछे का अर्थ क्या है?
IFS=$'\n'बशीवाद है (+ अन्य गोले, ANSI-C उद्धरण का उपयोग करें , वर्कअराउंड के लिए stackoverflow.com/questions/10748703/…
जवाबों:
IFS"आंतरिक क्षेत्र विभाजक" के लिए खड़ा है। इसका उपयोग शेल द्वारा यह निर्धारित करने के लिए किया जाता है कि शब्द विभाजन कैसे किया जाए, अर्थात शब्द सीमाओं को कैसे पहचाना जाए।
इस तरह के गोले को बैश में आज़माएं (अन्य गोले इसे अलग तरह से संभाल सकते हैं, उदाहरण के लिए zsh):
mystring="foo:bar baz rab"
for word in $mystring; do
echo "Word: $word"
done
IFSव्हाट्सएप वर्णों के लिए डिफ़ॉल्ट मान (सटीक होने के लिए: स्थान, टैब और न्यूलाइन)। प्रत्येक वर्ण शब्द सीमा हो सकता है। इसलिए, डिफ़ॉल्ट मान के साथ IFS, ऊपर का लूप प्रिंट होगा:
Word: foo:bar
Word: baz
Word: rab
दूसरे शब्दों में, शेल सोचता है कि व्हॉट्सएप एक शब्द सीमा है।
अब, IFS=:लूप निष्पादित करने से पहले सेटिंग का प्रयास करें । इस बार, परिणाम है:
Word: foo
Word: bar baz rab
अब, शेल mystringशब्दों में भी विभाजित होता है - लेकिन अब, यह केवल एक बृहदान्त्र को शब्द सीमा मानता है।
का पहला वर्ण IFSविशेष है: इसका उपयोग विशेष $*चर का उपयोग करते समय आउटपुट में शब्दों को परिसीमित करने के लिए किया जाता है (उदाहरण उन्नत बैश स्क्रिप्टिंग गाइड से लिया गया है , जहाँ आप विशेष चर जैसे अधिक जानकारी भी पा सकते हैं):
$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z
से तुलना:
$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z
ध्यान दें कि दोनों उदाहरणों में, खोल अभी भी पात्रों के सभी व्यवहार करेगा :, -और ;शब्द सीमाओं के रूप में। केवल एक चीज जो बदलती है वह है व्यवहार $*।
एक और महत्वपूर्ण बात यह है कि तथाकथित "IFS व्हाट्सएप" का इलाज कैसे किया जाता है । मूल रूप से, जैसे ही IFSव्हाट्सएप वर्ण शामिल होते हैं, अग्रणी और अनुगामी व्हाट्सएप को प्रसंस्करण से पहले विभाजित होने के लिए स्ट्रिंग से छीन लिया जाता है और लगातार व्हाट्सएप वर्णों के अनुक्रम के साथ-साथ खेतों को भी परिसीमित करता है। हालांकि, यह केवल उन व्हाट्सएप पात्रों पर लागू होता है जो वास्तव में मौजूद हैं IFS।
उदाहरण के लिए, आइए स्ट्रिंग "a:b:: c d "(अनुगामी स्थान और दो अंतरिक्ष वर्णों के बीच cऔर d) को देखें।
IFS=:: यह चार क्षेत्रों में विभाजित किया गया "a", "b", ""(रिक्त स्ट्रिंग) और " c d "(फिर से, इन दोनों के बीच रिक्त स्थान cऔर d)। अंतिम क्षेत्र में अग्रणी और अनुगामी व्हाट्सएप पर ध्यान दें।IFS=' :', यह पांच क्षेत्रों में विभाजित किया गया: "a", "b", ""(रिक्त स्ट्रिंग), "c"और "d"। कहीं भी कोई अग्रणी और अनुगामी व्हॉट्सएप नहीं।ध्यान दें कि एकाधिक, लगातार व्हाट्सएप वर्ण दूसरे उदाहरण में दो क्षेत्रों का परिसीमन करते हैं, जबकि एकाधिक, लगातार कॉलोन नहीं करते हैं (क्योंकि वे व्हाट्सएप वर्ण नहीं हैं)।
के लिए के रूप में IFS=$'\n', यह एक है ksh93भी द्वारा समर्थित वाक्य रचना bash, zsh, mkshऔर FreeBSD sh(सभी गोले के बीच बदलाव के साथ)। बैश मैनपेज का हवाला देते हुए:
$ 'स्ट्रिंग' रूप के शब्द विशेष रूप से व्यवहार किए जाते हैं। शब्द "स्ट्रिंग" तक फैलता है, बैकस्लैश-एस्कैप्ड अक्षरों के साथ एएनएसआई सी मानक द्वारा निर्दिष्ट किया गया है।
\nएक नई रेखा के लिए भागने का क्रम है, इसलिए IFSअंत में एक नई पंक्ति वर्ण पर सेट किया जा रहा है।
bashस्क्रिप्टिंग गाइड, या जो भी हो, के बजाय POSIX कल्पना को पढ़ने और समझने के लिए बहुत बेहतर करेंगे । मुख्य में, लिंक पर उपलब्ध जानकारी जैसे कि महत्वपूर्ण तरीकों की कमी है। वैसे भी, शेल विभाजन के विषय में दो महत्वपूर्ण बिंदुओं की याद आती है - ग्लोबिंग और आईएफएस व्हाट्सएप।
unset IFSशेल कैसे की तुलना में बहुत अलग व्यवहार करता है IFS=। इसके अलावा IFS में पहली बाइट विशेष "${named_array[*]}"रूप से अच्छी तरह से है - लेकिन न तो कोई
$IFSदो मुख्य चीजों में से एक है जो सूची के संदर्भ में एक अछूता चर का विस्तार करने पर किया जाता है (यह ऑपरेटर splitका हिस्सा है split+glob)। अन्य एक ग्लोबिंग है। कार्य विभाजन का उपयोग करते समय, आपको आमतौर पर भाग set -fको अक्षम करने के लिए जारी करने की आवश्यकता होती है glob।
$IFSread
डॉलर के एकल उद्धरणों के अंदर, कुछ पात्रों का मूल्यांकन विशेष रूप से किया जाता है। उदाहरण के लिए, \nनई लाइन में अनुवाद किया गया है।
तो, यह विशेष लाइन वैरिएबल IFS को नईलाइन प्रदान करती है। IFS, बदले में, बैश में एक विशेष चर है: आंतरिक क्षेत्र विभाजक। जैसा man bashकहता है, वैसा
विस्तार के बाद शब्द विभाजन के लिए और
readबिलिन कमांड के साथ शब्दों में लाइनों को विभाजित करने के लिए उपयोग किया जाता है । डिफ़ॉल्ट मान है<space><tab><newline>।
dollared single quotesजो सरल सिंगल कोट्स से अलग है।
संक्षिप्त रूप में, IFS=$'\n'नई \nवैरिएबल को असाइन करें IFS।
$'string'निर्माण एक उद्धृत तंत्र है जो एएनएसआई सी को भागने के अनुक्रम की तरह डिकोड करता है। इस वाक्य रचना से आता है ksh93, और जैसे आधुनिक खोल करने के लिए पोर्टेबल था bash, zsh, pdksh, busybox sh।
यह सिंटैक्स POSIX द्वारा परिभाषित नहीं है, लेकिन SUS अंक 7 के लिए स्वीकार किया गया था ।
मैंने $IFSउदाहरण के माध्यम से व्याख्या करना पसंद किया :
मान लीजिए कि आप cp या mv या किसी अन्य फ़ाइल को विफल करना चाहते हैं, तो IFS डिफॉल्ट से खाली है, जब आपकी फ़ाइलों में मेटा चार या स्पेस जैसे:
Linux Administration.pdfया Free Software Fundation.ogg, निश्चित रूप से आपके पास प्रोबेलम होगा, क्योंकि लिनक्स एक पर विचार करता है अलग पैराम और प्रशासक एक अलग पैरा मानते हैं। यदि बैश है built-in variable, तो आप इसे शुरू कर सकते हैं IFS==$(echo -en "\n\b"), फिर फ़ाइल नाम के बीच किसी भी मेटा चार और स्पेस को छोड़ दें, उदाहरण के लिए:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS