Bash scripting में IFS = $ '\ n' का अर्थ क्या है?


163

बैश शेल स्क्रिप्ट की शुरुआत में निम्नलिखित पंक्ति है:

IFS=$'\n'

प्रतीकों के इस संग्रह के पीछे का अर्थ क्या है?


3
यह भी देखें unix.stackexchange.com/questions/26784/understanding-ifs और सवाल यह हवाला दिया है।
गाइल्स

vim सिंटैक्स मेरे लिए इसे एक त्रुटि के रूप में रेखांकित करता है; ठीक कर?
Theonlygusti

IFS=$'\n'बशीवाद है (+ अन्य गोले, ANSI-C उद्धरण का उपयोग करें , वर्कअराउंड के लिए stackoverflow.com/questions/10748703/…
pevik

जवाबों:


199

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) को देखें।

  1. साथ IFS=:: यह चार क्षेत्रों में विभाजित किया गया "a", "b", ""(रिक्त स्ट्रिंग) और " c d "(फिर से, इन दोनों के बीच रिक्त स्थान cऔर d)। अंतिम क्षेत्र में अग्रणी और अनुगामी व्हाट्सएप पर ध्यान दें।
  2. साथ IFS=' :', यह पांच क्षेत्रों में विभाजित किया गया: "a", "b", ""(रिक्त स्ट्रिंग), "c"और "d"। कहीं भी कोई अग्रणी और अनुगामी व्हॉट्सएप नहीं।

ध्यान दें कि एकाधिक, लगातार व्हाट्सएप वर्ण दूसरे उदाहरण में दो क्षेत्रों का परिसीमन करते हैं, जबकि एकाधिक, लगातार कॉलोन नहीं करते हैं (क्योंकि वे व्हाट्सएप वर्ण नहीं हैं)।

के लिए के रूप में IFS=$'\n', यह एक है ksh93भी द्वारा समर्थित वाक्य रचना bash, zsh, mkshऔर FreeBSD sh(सभी गोले के बीच बदलाव के साथ)। बैश मैनपेज का हवाला देते हुए:

$ 'स्ट्रिंग' रूप के शब्द विशेष रूप से व्यवहार किए जाते हैं। शब्द "स्ट्रिंग" तक फैलता है, बैकस्लैश-एस्कैप्ड अक्षरों के साथ एएनएसआई सी मानक द्वारा निर्दिष्ट किया गया है।

\nएक नई रेखा के लिए भागने का क्रम है, इसलिए IFSअंत में एक नई पंक्ति वर्ण पर सेट किया जा रहा है।


3
यह अच्छा है, लेकिन, मेरी राय में, आप bashस्क्रिप्टिंग गाइड, या जो भी हो, के बजाय POSIX कल्पना को पढ़ने और समझने के लिए बहुत बेहतर करेंगे । मुख्य में, लिंक पर उपलब्ध जानकारी जैसे कि महत्वपूर्ण तरीकों की कमी है। वैसे भी, शेल विभाजन के विषय में दो महत्वपूर्ण बिंदुओं की याद आती है - ग्लोबिंग और आईएफएस व्हाट्सएप।
15

@mikeserv धन्यवाद, मैंने IFS व्हाट्सएप पर कुछ जानकारी जोड़ी। उस के बारे में पता नहीं था। :)
तबल्यू

4
प्रासंगिक के रूप में नहीं, लेकिन अगर आप उत्सुक हैं, तो आप यह देखना चाहते हैं कि unset IFSशेल कैसे की तुलना में बहुत अलग व्यवहार करता है IFS=। इसके अलावा IFS में पहली बाइट विशेष "${named_array[*]}"रूप से अच्छी तरह से है - लेकिन न तो कोई
फर्क नहीं पड़ता

कुछ और बिंदु: 1- शब्द का विभाजन, द्वारा शासित $IFSदो मुख्य चीजों में से एक है जो सूची के संदर्भ में एक अछूता चर का विस्तार करने पर किया जाता है (यह ऑपरेटर splitका हिस्सा है split+glob)। अन्य एक ग्लोबिंग है। कार्य विभाजन का उपयोग करते समय, आपको आमतौर पर भाग set -fको अक्षम करने के लिए जारी करने की आवश्यकता होती है glob
स्टीफन चेजेलस

3
3- $IFSread
बिलियन

22

डॉलर के एकल उद्धरणों के अंदर, कुछ पात्रों का मूल्यांकन विशेष रूप से किया जाता है। उदाहरण के लिए, \nनई लाइन में अनुवाद किया गया है।

तो, यह विशेष लाइन वैरिएबल IFS को नईलाइन प्रदान करती है। IFS, बदले में, बैश में एक विशेष चर है: आंतरिक क्षेत्र विभाजक। जैसा man bashकहता है, वैसा

विस्तार के बाद शब्द विभाजन के लिए और readबिलिन कमांड के साथ शब्दों में लाइनों को विभाजित करने के लिए उपयोग किया जाता है । डिफ़ॉल्ट मान है <space><tab><newline>


5
+1 का उल्लेख करने के लिए dollared single quotesजो सरल सिंगल कोट्स से अलग है।
स्नोक्रैश

2
डॉलर वाले एकल उद्धरणों के उल्लेख के लिए +1 कहने के लिए @Snowcrash +1 जो सरल एकल उद्धरणों से अलग है । क्षमा करें, यह मदद नहीं कर सकता :) लेकिन वास्तव में यह इंगित करने के लिए एक बहुत अच्छी बात है क्योंकि यह महत्वपूर्ण है!
प्रियेफ़टन

1
@Pryftan +1 +1 के लिए +1 ... आप जानते हैं ... यह वास्तव में महत्वपूर्ण है।
0xc0de

@ 0xc0de निश्चित रूप से सहमत हैं! उसके लिए धन्यवाद! :)
Pryftan

15

संक्षिप्त रूप में, IFS=$'\n'नई \nवैरिएबल को असाइन करें IFS

$'string'निर्माण एक उद्धृत तंत्र है जो एएनएसआई सी को भागने के अनुक्रम की तरह डिकोड करता है। इस वाक्य रचना से आता है ksh93, और जैसे आधुनिक खोल करने के लिए पोर्टेबल था bash, zsh, pdksh, busybox sh

यह सिंटैक्स POSIX द्वारा परिभाषित नहीं है, लेकिन SUS अंक 7 के लिए स्वीकार किया गया था ।


-1

मैंने $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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.