Bash دو نوع پارامتر فراهم میکند: مقادیر «اسکالر» و آرایهها. یک مقدار اسکالر میتواند یک رشته یا یک عدد باشد؛ این مقدار نمایندهی یک «چیز» منفرد است.
در بیشتر موارد، مقادیر اسکالر برای نگهداری دادههای شما کافیاند. اما گاهی لازم است لیستی از مقادیر اسکالر را ذخیره کنید. در این صورت از یک آرایه استفاده میکنید.
آرایهها دو نوعاند:
بخشهای اول این سند به آرایههای با اندیس عددی میپردازد (که از این پس بهسادگی «آرایه» نامیده میشوند). جزئیات مربوط به آرایههای انجمنی در پایان میآید.
آرایههای Bash فقط میتوانند مقادیر اسکالر را ذخیره کنند. امکان ساختن یک آرایهی دوبعدی (آرایهی آرایهها) وجود ندارد.
میتوانید یک آرایه را با انتساب دادن یک لیست عنصر داخل پرانتز (احتمالاً خالی) به یک متغیر مقداردهی اولیه کنید.
myarray=("one" "two" "three")
همانطور که در هر انتساب متغیر رایج است، نباید دور علامت مساوی فاصلهای باشد.
توجه کنید که بین عنصرها هیچ جداکنندهی ویرگولی وجود ندارد؛ این یک لیست از رشتهها است که با فاصله از هم جدا شدهاند.
در واقع، میزان فاصلهی داخل پرانتزها کاملاً دلبخواه است. خط جدید هم مجاز است؛ هر تعداد که میخواهید برای خوانایی بیشتر به کار ببرید.
myarray=(
"first element"
"second element"
"this is the last element"
)
اگر به این شکل لیستی از رشتهها را به یک متغیر آرایه انتساب دهید، رشتهی اول در اندیس صفر، رشتهی بعدی در اندیس یک، بعدی در اندیس دو و به همین ترتیب ذخیره میشود.
میتوان با مشخص کردن اندیسهای مورد نیاز، یک «آرایهی پراکنده» مقداردهی اولیه کرد.
raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
تکرار میکنیم: اندیسهای آرایه از صفر شروع میشوند. این قطعه کد «true» را چاپ میکند:
myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false
میتوانید از دستور declare (یا local درون یک تابع) استفاده کنید تا مشخص کنید که یک متغیر آرایه نگه میدارد.
declare -a myarray
روش اصطلاحیتر این است که فقط یک لیست داخل پرانتز (احتمالاً خالی) را برای مقداردهی اولیهی متغیر انتساب دهید.
همانطور که در نکتهی بالا دیدید، نحوهی نگارش دسترسی به یک عنصر آرایه ${myarray[$index]} است.
اندیس داخل کروشه نوشته میشود.
آکولادها الزامیاند.
برای آرایههای با اندیس عددی، اندیس یک عبارت حسابی است. راهنمای Bash میگوید:
درون یک عبارت حسابی، متغیرهای شل را میتوان بدون استفاده از نحوهی نگارش بسط پارامتر، با اسم نیز ارجاع داد.
این یعنی برای بسط «سادهی» متغیر، $ لازم نیست.
میتوانید عنصرها را به این شکل به دست آورید، که کمی خواناتر است:
i=5
echo "${myarray[i]}"
# ..............^
اگر اندیس دادهشده در آرایه وجود نداشته باشد، نتیجهی بسط یک رشتهی خالی است.
برای انتساب به یک عنصر خاص از آرایه، از این نحوهی نگارش استفاده کنید:
myarray[10]="hello"
برای افزودن به انتهای یک آرایه، از عملگر انتساب الحاقی += و از پرانتزها استفاده کنید:
myarray+=("new element 1" "new element 2")
معمولاً لازم است روی مقدارهای یک آرایه پیمایش کنید. از یک حلقهی For استفاده کنید (همان که در مفهوم حلقه دیدید):
myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
echo "$value"
done
به نحوهی نگارش ویژهی بسط آرایه توجه کنید: "${myarray[@]}"
این شکل از بسط پارامتر، مقدارهای آرایه را بهصورت کلمههای جداگانه جایگذاری میکند.
تا حدودی معادل این است:
for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"
شکل "${myarray[@]}" با آرایههای پراکنده هم کار میکند و فقط به مقدارهای تعریفشده بسط مییابد.
این بسط ویژه، که در آن اندیس @ است، تنها درون دابلکوتیشن ویژه محسوب میشود.
در اینجا چند قطعهی دیگر از نحوهی نگارش ویژه را میبینیم که برای پیمایش یک آرایه لازم داریم. اینها در راهنما، در بخش بسط پارامترهای شل توضیح داده شدهاند.
برای یافتن طول یک آرایه، از ${#myarray[@]} استفاده کنید، با یک # پیش از اسم.
منظور از «طول» یک آرایه، تعداد عنصرهای آن است.
برای استخراج لیست اندیسهای یک آرایه، از "${!myarray[@]}" استفاده کنید، با یک ! پیش از اسم و با قرار دادن بسط در دابلکوتیشن.
برای آرایههای با اندیس عددی، اندیسها به ترتیب عددی بسط مییابند.
گاهی هم به اندیس نیاز دارید و هم به مقدار. چند راه برای این کار وجود دارد.
وقتی میدانید اندیسها یک دنبالهی بدون وقفه میسازند، میتوانید از یک حلقهی For حسابی استفاده کنید.
for ((i = 0; i < ${#myarray[@]}; i++)); do
echo "$i -> ${myarray[i]}"
done
به نحوهی نگارش ${#myarray[@]} توجه کنید، با کاراکتر # جلوی اسم آرایه.
چون آرایهها اندیسگذاری را از صفر شروع میکنند، آخرین اندیس آرایه یکی کمتر از طول آرایه است.
وقتی آرایه پراکنده است، میتوانید از این شکل استفاده کنید:
for index in "${!raindrops[@]}"; do
echo "$index -> ${raindrops[index]}"
done
به نحوهی نگارش ${!myarray[@]} توجه کنید، با کاراکتر ! جلوی اسم آرایه.
اگر میخواهید محتوای یک آرایه را ببینید، از دستور declare با گزینهی -p استفاده کنید:
a=("the 'first' element"
second
third
'the "last" element')
declare -p a
این کار محتوا را با نقلقول استاندارد شل چاپ میکند.
declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")
تکرار میکنیم که آرایههای انجمنی برای اندیسها از رشته استفاده میکنند، نه از عدد. همهی آنچه در بالا نوشته شد برای آرایههای انجمنی هم برقرار است، اما با تفاوتهای کوچک. بهطور کلی، ما بهجای «اندیس» از اصطلاح «کلید» استفاده میکنیم: آرایههای انجمنی کلیدها را به مقدارها نگاشت میکنند.
برخلاف آرایههای معمولی، آرایههای انجمنی باید اعلان شوند.
از گزینهی -A برای declare (یا local درون یک تابع) استفاده کنید:
declare -A mymap
myfunc() {
local -A my_local_map
# ...
}
جفتهای کلید-مقدار درون لیست داخل پرانتز مشخص میشوند:
mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap
این خروجی را میدهد:
declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
توجه داشته باشید که آرایههای انجمنی بدون ترتیب هستند.
اعلان و مقداردهی اولیه میتوانند در یک خط انجام شوند.
declare -A mymap=([first]=foo [second]=bar [third]=baz)
در نسخههای اخیر Bash، مقداردهی اولیه میتواند از یک لیست (key value key value ...) استفاده کند.
declare -A mymap=(first foo second bar third baz)
برای دسترسی به عنصرها از همان نحوهی نگارشی که پیشتر دیدیم استفاده میشود: ${mymap[$key]}.
کلیدهای آرایهی انجمنی در بستر حسابی ارزیابی نمیشوند. نحوهی نگارش معمول بسط پارامتر لازم است.
انتساب از همان نحوهی نگارشی که پیشتر دیدیم استفاده میکند:
mymap[$key]="$value"
میتوانید برای پیمایش از یک حلقهی for value in "${mymap[@]}" استفاده کنید.
اما معمولاً میخواهید کلید هم همراه مقدار بیاید.
از نحوهی نگارش "${!mymap[@]}" که در بالا دیدیم استفاده کنید.
for key in "${!mymap[@]}"; do
echo "$key -> ${mymap[$key]}"
done
این خروجی را میدهد
second -> bar
first -> foo
third -> baz
باز هم تأکید میکنیم که کلیدها هیچ ترتیبی ندارند.