अस्थायी रूप से IFS को लूप से पहले बदलना [डुप्लिकेट]

Aug 16 2020

मुझे पता है कि SHELLवेरिएबल असाइनमेंट को कमांड से तुरंत पहले करने की अनुमति देता है, जैसे कि IFS=":" read a b c d <<< "$here_string"काम करता है ...

मैं सोच रहा था कि क्या ऐसे असाइनमेंट काम नहीं करते हैं जब लूप्स जैसे कंपाउंड स्टेटमेंट्स के साथ काम किया जाता है? मैंने ऐसा कुछ करने की कोशिश की, IFS=":" for i in $PATH; do echo $i; doneलेकिन इसके परिणामस्वरूप एक वाक्यविन्यास त्रुटि हुई। मैं हमेशा कुछ ऐसा कर सकता oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS"था, लेकिन मैं जानना चाहता था कि क्या कोई ऐसा तरीका है जिससे मैं forलूप्स जैसे कंपाउंड स्टेटमेंट के लिए इनलाइन असाइनमेंट काम कर सकूं?

जवाब

3 Quasímodo Aug 16 2020 at 21:12

forएक आरक्षित शब्द है और इस प्रकार विशेष नियम हैं :

निम्नलिखित शब्दों को आरक्षित शब्दों के रूप में पहचाना जाएगा:

! {{मामला तब तक के लिए और जब तक हो सके तब तक एलीफैक एस्क फाई करें

यह मान्यता केवल तब होगी जब कोई भी अक्षर उद्धृत नहीं किया जाता है और जब इस शब्द का उपयोग किया जाता है:

  • एक कमांड का पहला शब्द

  • पहला शब्द के अलावा अन्य आरक्षित शब्दों में से एक निम्नलिखित मामले , के लिए , या में

  • एक मामले आदेश में तीसरा शब्द (केवल में इस मामले में मान्य है)

  • आदेश के लिए एक में तीसरा शब्द (केवल में और कर इस मामले में मान्य हैं)

अगर तुम कोशिश करो

IFS=":" for i in $PATH; do echo $i; done

, ऊपर दिए गए नियमों के अनुसार, यह forलूप नहीं है , क्योंकि कीवर्ड कमांड का पहला शब्द नहीं है। लेकिन आपके इरादे को हासिल किया जा सकता है

IFS=: printf '%s\n' $PATH

$PATH:उम्मीद के अनुसार शब्द विभाजन से गुजरना और प्रत्येक परिणामी शब्द द्वारा मुद्रित किया जाता है printf, उसके बाद एक नई पंक्ति।


आप इस मान्य दृष्टिकोण से परिचित हो सकते हैं:

while IFS= read -r line; do

whileकमांड का पहला शब्द है, और IFSअसाइनमेंट लागू होता है read, इसलिए सब ठीक है।