IFS = $ '\ n' का सटीक अर्थ क्या है?


124

यदि निम्न उदाहरण, जो IFSलाइन चर चरित्र के लिए पर्यावरण चर सेट करता है ...

IFS=$'\n'
  • क्या करता डॉलर साइन मतलब बिल्कुल ?
  • इस विशिष्ट मामले में यह क्या करता है?
  • मैं इस विशिष्ट उपयोग पर अधिक कहां पढ़ सकता हूं (Google खोजों में विशेष वर्णों की अनुमति नहीं देता है और मुझे नहीं पता कि अन्यथा क्या देखना है)?

मुझे पता है कि IFSपर्यावरण चर क्या है, और \nचरित्र क्या है (पंक्ति फ़ीड), लेकिन केवल निम्न रूप का उपयोग क्यों न करें: IFS="\n"(जो काम नहीं करता है)?

उदाहरण के लिए, यदि मैं किसी फ़ाइल की प्रत्येक पंक्ति के माध्यम से लूप करना चाहता हूं और लूप के लिए उपयोग करना चाहता हूं, तो मैं यह कर सकता हूं:

for line in (< /path/to/file); do
    echo "Line: $line"
done

हालाँकि, यह तब तक सही काम नहीं करेगा जब तक IFSएक पंक्ति फ़ीड वर्ण पर सेट नहीं किया जाता है। इसे काम पर लाने के लिए, मुझे यह करना होगा:

OLDIFS=$IFS
IFS=$'\n'
for line in (< /path/to/file); do
    echo "Line: $line"
done
IFS=$OLDIFS

नोट: मुझे एक ही काम करने के लिए दूसरे तरीके की आवश्यकता नहीं है, मैं पहले से ही कई अन्य को जानता हूं ... मैं केवल इसके बारे में उत्सुक हूं $'\n'और अगर कोई मुझे इस पर स्पष्टीकरण दे सकता है तो मुझे आश्चर्य होगा।

जवाबों:


161

आम तौर पर bashस्ट्रिंग शाब्दिकों में भागने के दृश्यों की व्याख्या नहीं करता है इसलिए यदि आप लिखते हैं \nया "\n"या '\n', यह एक लाइनब्रेक नहीं है - यह अक्षर है n(पहले मामले में) या पत्र के बाद एक बैकस्लैश n(अन्य दो मामलों में)।

$'somestring'भागने के अनुक्रम के साथ स्ट्रिंग शाब्दिक के लिए एक वाक्यविन्यास है । तो इसके विपरीत '\n', $'\n'वास्तव में एक लाइनब्रेक है।


2
ऐसा बिलकुल नहीं है - \nसिर्फ एक (बच गया) अक्षर n है। आप सही हैं '\n'और "\n"n के बाद बैकलैश हैं।
रोमन चेप्लाकाका

15
ध्यान दें कि $'\n'यह विशिष्ट है - यह POSIX शेल ( /bin/sh) में काम नहीं करेगा । POSIX- अनुरूप तरीके से एक ही प्रभाव प्राप्त करने के लिए, आप टाइप कर सकते हैं IFS=', फिर एक वास्तविक न्यूलाइन वर्ण टाइप करने के लिए हिट करें, फिर समापन टाइप करें'
रिचर्ड हैनसेन

23
IFS=$(echo -e '\n')इसे POSIX- संगत तरीके से भी करना चाहिए।
विनीत

12
@ विनीत - इसने मुझे अपमानजनक टिप्पणी करने के लिए विराम दिया। हालांकि यह है Posix-सही, यह नहीं काम करता है - बैश में आदेश प्रतिस्थापन ऑपरेटरों सब अनुगामी न्यू लाइन वर्ण निकाल दें। अधिक विस्तार के लिए इसे देखें ।
डिजिटल ट्रामा

9
@DigitalTrauma मुझे लगता है कि यह भी POSIX -eनहीं है : परिभाषित नहीं है, और XSI एक्सटेंशन के रूप में कार्य \nकिए बिना -e: pubs.opengroup.org/onlinepubs/9699919799/utilities/…printf '\n'चट्टानों;)
सिरो सेंटिल्ली 郝海东 病 iro iro 法轮功 '-

20

बस निर्माण इसकी देने के लिए आधिकारिक नाम : प्रपत्र के तार $'...'कहा जाता है एएनएसआई सी उद्धृत तार

यही है, जैसा कि [ANSI] C स्ट्रिंग्स में, बैकलैश एस्केप सीक्वेंस को पहचाना और उनके शाब्दिक समकक्ष के लिए विस्तारित किया जाता है (समर्थित एस्केप सीक्वेंस की पूरी सूची के लिए नीचे देखें)।

इस विस्तार के बाद , $'...'तार तार के समान व्यवहार करते '...'हैं - यानी, उन्हें ऐसे शाब्दिक के रूप में माना जाता है जो किसी भी [आगे] शेल अभियानों के अधीन नहीं हैं

उदाहरण के लिए, $'\n'एक शाब्दिक न्यूलाइन वर्ण का विस्तार होता है - जो एक नियमित बैश स्ट्रिंग शाब्दिक है (चाहे '...'या "..."नहीं) नहीं कर सकता। [1]

एक और दिलचस्प विशेषता यह है कि एएनएसआई सी-उद्धृत स्ट्रिंग्स '(एकल उद्धरण) से बच सकते हैं\' , जो '...'(नियमित रूप से एकल-उद्धृत स्ट्रिंग्स नहीं कर सकते हैं):

echo $'Honey, I\'m home' # OK; this cannot be done with '...'

समर्थित एस्केप दृश्यों की सूची :

बैकस्लैश एस्केप सीक्वेंस, यदि मौजूद हैं, तो निम्नानुसार डिकोड किए जाते हैं:

एक चेतावनी (घंटी)

\ b बैकस्पेस

\ e \ E एक बच चरित्र (ANSI C नहीं)

\ f फॉर्म फ़ीड

\ n न्यूलाइन

\ r गाड़ी वापसी

\ t क्षैतिज टैब

\ v ऊर्ध्वाधर टैब

\ backslash

\' एकल बोली

\" दोहरे उद्धरण

\ nn आठ-बिट वर्ण जिसका मान ऑक्टल मान nnn है (एक से तीन अंक)

\ xHH आठ-बिट वर्ण जिसका मान हेक्साडेसिमल मान HH (एक या दो हेक्स अंक) है

\ uHHHH यूनिकोड (ISO / IEC 10646) वर्ण जिसका मान हेक्साडेसिमल मान HHHH (एक से चार हेक्स अंक) है

\ UHHHHHHHH यूनिकोड (ISO / IEC 10646) वर्ण जिसका मान हेक्साडेसिमल मान HHHHHHHH (एक से आठ हेक्स अंक) है

\ cx एक नियंत्रण-x वर्ण

विस्तारित परिणाम एकल-उद्धृत है, जैसे कि डॉलर का चिह्न मौजूद नहीं था।


[१] आप, हालांकि, '...' और "..." तार में वास्तविक नई कथनों को एम्बेड कर सकते हैं; यानी, आप ऐसे स्ट्रिंग्स को परिभाषित कर सकते हैं जो कई लाइनों को फैलाते हैं।


16

से http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html :

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

मुझे लगता है कि यह उचित एएनएसआई-सी मानक को लाइन फीड से बचने के लिए स्क्रिप्ट को मजबूर कर रहा है।


8

डिफ़ॉल्ट IFS को पुनर्प्राप्त करना - OLDIFS=$IFSयह आवश्यक नहीं है। डिफ़ॉल्ट IFS को ओवरराइड करने से बचने के लिए नए IFS को सबस्क्रिप्शन में चलाएं:

ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )

इसके अलावा मुझे विश्वास नहीं है कि आप पुराने IFS को पूरी तरह से ठीक कर पाएंगे। लाइन ब्रेकिंग से बचने के लिए आपको इसे डबल कोट करना चाहिए जैसे कि OLDIFS="$IFS"


2
यह वास्तव में उपयोगी तकनीक है। मैं सिर्फ एक क्लीनर खोल में शामिल होने के लिए इसका इस्तेमाल किया args=$(IFS='&'; echo "$*"):। बॉर्न शेल के अनुकूल तरीके से बहाल IFSकरने $' \t\n'का कोई मतलब नहीं है।
जेबरल

पुन Besides I don't really believe you recover the old IFS fully: शब्द बंटवारे है नहीं तो चर कार्य की आरएचएस पर प्रदर्शन (लेकिन बोली हटाने है), OLDIFS=$IFSऔर OLDIFS="$IFS"उसी तरह व्यवहार करते हैं।
mklement0

3

ANSI C- उद्धृत स्ट्रिंग्स एक प्रमुख बिंदु है। @ Mklement0 के लिए धन्यवाद।

आप कमांड ओडी के साथ एएनएसआई सी-उद्धृत स्ट्रिंग्स का परीक्षण कर सकते हैं।

echo -n $'\n' | od -c
echo -n '\n' | od -c
echo -n $"\n" | od -c
echo -n "\n" | od -c

आउटपुट:

0000000  \n  
0000001

0000000   \   n   
0000002

0000000   \   n   
0000002

0000000   \   n   
0000002

आप आउटपुट द्वारा स्पष्ट रूप से अर्थ जान सकते हैं।


-7

यह वैरिएबल से मान प्राप्त करने जैसा है:

VAR='test'
echo VAR
echo $VAR

भिन्न हैं, इसलिए डॉलर का संकेत मूल रूप से सामग्री का मूल्यांकन करता है।


6
इसका चर से कोई लेना-देना नहीं है। $'FOO'(इसके विपरीत $FOOजो यह सवाल था कि नहीं था) एक स्ट्रिंग शाब्दिक है। यदि आप निष्पादित करते हैं echo $'VAR', तो आप देखेंगे कि यह स्ट्रिंग को प्रिंट करता है VAR, नहीं test
sepp2k
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.