ट्रैक
/
Bash
Bash
/
सिलेबस
/
ऐरे के बारे में और जानकारी
ऐर

ऐरे के बारे में और जानकारी में Bash

{one: "1 अभ्यास", other: "%{count} अभ्यास"}

ऐरे के बारे में और जानकारी के बारे में

हमने ऐरे अध्याय में ऐरे का परिचय दिया था। यह दस्तावेज़ ऐरे का उपयोग करने के और तरीके दिखाएगा।

ऐरे के एलिमेंट को एक ही स्ट्रिंग में जोड़ना

पिछले ऐरे अध्याय में आपने "${myarray[@]}" देखा था, जिसमें @ इंडेक्स का उपयोग ऐरे को अलग-अलग एलिमेंट में फैलाने के लिए किया जाता है। लेकिन कभी-कभी आप सभी एलिमेंट को एक ही स्ट्रिंग में जोड़ना चाहते हैं। इसके लिए * इंडेक्स का उपयोग कीजिए:

echo "${myarray[*]}"

आपको इस एक्सपैंशन को डबल कोट्स में बंद करना आवश्यक है।

Bash IFS इन-बिल्ट वेरिएबल के पहले अक्षर को सेपरेटर अक्षर के रूप में उपयोग करता है। डिफ़ॉल्ट रूप से $IFS में स्पेस, टैब और न्यूलाइन शामिल होते हैं।

myarray=(one two three four)
mystring="${myarray[*]}"
declare -p mystring
# => declare -- mystring="one two three four"

हम IFS वेरिएबल को बदलकर कोई दूसरा सेपरेटर अक्षर उपयोग कर सकते हैं:

myarray=(one two three four)
IFS=","
mystring="${myarray[*]}"
declare -p mystring
# => declare -- mystring="one,two,three,four"
Advanced
हम इसे एक फंक्शन में समेट सकते हैं। विवरण के लिए क्लिक कीजिए।
join() {
    local IFS=$1
    shift
    local elements=("$@")
    echo "${elements[*]}"
}

join ":" "${myarray[@]}"     # note, the "@" index
# => "one:two:three:four"

फंक्शन के अंदर IFS को लोकल बनाने का मतलब है कि हमें पुरानी वैल्यू सहेजकर बाद में उसे ग्लोबल स्कोप में उसकी पिछली वैल्यू पर वापस लौटाने की ज़रूरत नहीं पड़ती।

इसे और बेहतर बनाने के लिए, विशेष पैरामीटर "$*" को कोट्स में रखने पर वही काम करता है, इसलिए हमें फंक्शन के आर्गुमेंट की एक कॉपी सहेजने की ज़रूरत नहीं होती:

join() {
    local IFS=$1
    shift
    echo "$*"
}
फंक्शन का उपयोग किए बिना, सबशेल में IFS बदलना, वर्तमान शेल में इसे बदलने से बचने का अच्छा तरीका है। विवरण के लिए क्लिक कीजिए।
(IFS=","; echo "${myarray[*]}")

ये कोष्ठक एक सबशेल बनाते हैं (वर्तमान शेल की एक कॉपी)। जब कोष्ठक के अंदर दिए गए कमांड पूरे हो जाते हैं, तो सबशेल बाहर निकल जाता है, और बदला हुआ IFS वेरिएबल गायब हो जाता है।

ध्यान दीजिए कि यह काम नहीं करेगा: IFS="," echo "${myarray[*]}"। यहाँ पैरामीटर एक्सपैंशन पहले हो जाता है, यानी उससे पहले कि शेल बदले हुए IFS वेरिएबल को echo कमांड पर लागू करे।

ऐरे के स्लाइस

आपने "${variable:offset:length}" पैरामीटर एक्सपैंशन देखा होगा, जो वेरिएबल की वैल्यू के एक सबस्ट्रिंग में फैलता है। ऐरे के साथ भी हम यही काम कर सकते हैं, जिससे ऐरे का एक स्लाइस फैल जाता है।

myarray=(one two three four)

subarray=("${myarray[@]:0:2}")
declare -p subarray
# => declare -a subarray=([0]="one" [1]="two")

subarray=("${myarray[@]:1:3}")
declare -p subarray
# => declare -a subarray=([0]="two" [1]="three" [2]="four")

लंबाई वाला हिस्सा छोड़ देने का मतलब है "ऑफ़सेट से लेकर ऐरे के अंत तक":

subarray=("${myarray[@]:2}")
declare -p subarray
# => declare -a subarray=([0]="three" [1]="four")

फंक्शन को ऐरे पास करना

यह उतना सीधा नहीं है जितना आपकी जानी-पहचानी दूसरी भाषाओं में होता है। फंक्शन को ऐरे पास करने के दो मुख्य तरीके हैं।

एलिमेंट पास करना

पहले तरीके में, आप ऐरे की सभी वैल्यू पास करते हैं और फंक्शन के अंदर उन्हें एक लोकल ऐरे में इकट्ठा कर लेते हैं।

myfunc() {
    local array_copy=("$@")
    # do stuff with array_copy
    declare -p array_copy
}

array_original=(11 22 33 44)
myfunc "${array_original[@]}"

फंक्शन का ऐरे इन वैल्यू की एक कॉपी रखता है। फंक्शन के अंदर ऐरे में किए गए कोई भी बदलाव बाहरी स्कोप में नहीं दिखते।

ऐरे का नाम पास करना

यह तरीका उस "पास बाय रेफ़रेंस" सुविधा जैसा है जिसे आप दूसरी भाषाओं से जानते होंगे। आप ऐरे का नाम एक स्ट्रिंग के रूप में पास करते हैं। फंक्शन "नेमरेफ़" अट्रिब्यूट वाला एक लोकल वेरिएबल बनाता है। यह लोकल ऐरे और ग्लोबल ऐरे (जिसका नाम हमने पास किया था) एक ही ऐरे हैं।

myfunc() {
    # note the `-n` option
    local -n local_array=$1

    # do stuff with local_array
    for i in "${!local_array[@]}"; do
        printf '%d => %s\n' "$i" "${local_array[i]}"
    end

    # we can mutate it
    local_array+=(55 66 77)
}

array_original=(11 22 33 44)
myfunc "array_original"

# show the mutated array
declare -p array_original
# => declare -a array_original=([0]="11" [1]="22" [2]="33" [3]="44" [4]="55" [5]="66" [6]="77")

नेमरेफ़ असोसिएटिव ऐरे और "स्केलर" वेरिएबल (जिनमें एक स्ट्रिंग वैल्यू होती है) के साथ भी काम करते हैं।

Note

फंक्शन के अंदर declare -p local_array ज़्यादा मददगार नहीं होता। यह बस declare -n local_array="array_original" दिखा देता है। पास किए गए ऐरे के नाम की जाँच करके आप ऐरे की विस्तृत जानकारी पा सकते हैं: declare -p "$1"

Caution

ध्यान रखिए कि लोकल ऐरे का नाम पास किए गए ऐरे से अलग हो। कोड फिर भी चलेगा, लेकिन यह इस तरह "सर्कुलर नेम रेफ़रेंस" चेतावनियाँ दिखाएगा:

myfunc() {
    local -n a=$1
    local IFS=,
    echo "${a[*]}"
}

# same name as the function's local variable
a=(one two three)
myfunc a
bash: local: warning: a: circular name reference
bash: warning: a: circular name reference
bash: warning: a: circular name reference
bash: warning: a: circular name reference
one,two,three

पोज़िशनल पैरामीटर "ऐरे जैसे" होते हैं

उन शेल में जो सिर्फ POSIX मानक का पालन करते हैं (जैसे ash और dash), ऐरे नहीं होते। इसके सबसे नज़दीक आप पोज़िशनल पैरामीटर के उपयोग से पहुँच सकते हैं।

  • पोज़िशनल पैरामीटर इंडेक्स से एक्सेस किए जाते हैं: $1, $2, आदि।
  • इन्हें "$@" के साथ अलग-अलग एलिमेंट में फैलाया जाता है।
  • इन्हें "$*" के साथ एक ही स्ट्रिंग में जोड़ा जाता है।
  • पैरामीटर की संख्या $# होती है।

इन्हें वैल्यू असाइन करने के लिए set कमांड का उपयोग कीजिए:

set -- one two three
set -- "$@" four

for item in "$@"; do
    echo "do something with $item"
done

अगर आपका उद्देश्य "पोर्टेबल" शेल स्क्रिप्ट लिखना है, तो आप वैल्यू की एक "लिस्ट" रखने के लिए पोज़िशनल पैरामीटर का उपयोग करेंगे।

GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।