การทำงานกับอาร์เรย์ใน Linux Shell Scripting – ตอนที่ 8
เราไม่สามารถจินตนาการถึงภาษาการเขียนโปรแกรมได้หากไม่มีแนวคิดเรื่องอาร์เรย์ ไม่สำคัญว่าจะนำไปใช้ในภาษาต่างๆ อย่างไร อาร์เรย์จะช่วยเราในการรวบรวมข้อมูล เหมือนหรือต่างกัน ภายใต้ชื่อสัญลักษณ์เดียวแทน
เนื่องจากเรากังวลเกี่ยวกับเชลล์สคริปต์ บทความนี้จะช่วยคุณลองใช้เชลล์สคริปต์บางตัวซึ่งใช้แนวคิดเรื่องอาร์เรย์นี้
การเริ่มต้นและการใช้งานอาร์เรย์
ด้วย bash เวอร์ชันใหม่กว่า รองรับอาร์เรย์หนึ่งมิติ อาร์เรย์สามารถประกาศอย่างชัดเจนโดย ประกาศ เชลล์ในตัว
declare -a var
แต่ไม่จำเป็นต้องประกาศตัวแปรอาเรย์เหมือนข้างบน เราสามารถแทรกแต่ละองค์ประกอบลงในอาร์เรย์ได้โดยตรงดังนี้
var[XX]=<value>
โดยที่ 'XX' หมายถึงดัชนีอาร์เรย์ หากต้องการยกเลิกการอ้างอิงองค์ประกอบอาร์เรย์ ให้ใช้ไวยากรณ์วงเล็บปีกกา เช่น
${var[XX]}
หมายเหตุ: การจัดทำดัชนีอาร์เรย์จะเริ่มต้นด้วย 0 เสมอ
อีกวิธีที่สะดวกในการเริ่มต้นอาร์เรย์ทั้งหมดคือการใช้วงเล็บคู่ดังที่แสดงด้านล่าง
var=( element1 element2 element3 . . . elementN )
ยังมีอีกวิธีหนึ่งในการกำหนดค่าให้กับอาร์เรย์ วิธีการเริ่มต้นนี้เป็นหมวดหมู่ย่อยของวิธีที่อธิบายไว้ก่อนหน้านี้
array=( [XX]=<value> [XX]=<value> . . . )
นอกจากนี้เรายังสามารถอ่าน/กำหนดค่าให้กับอาร์เรย์ในช่วงเวลาดำเนินการโดยใช้เชลล์ในตัว อ่าน
read -a array
ตอนนี้เมื่อรันคำสั่งข้างต้นภายในสคริปต์ มันจะรออินพุตบางส่วน เราจำเป็นต้องจัดเตรียมองค์ประกอบอาร์เรย์โดยคั่นด้วยช่องว่าง (และไม่ใช่การขึ้นบรรทัดใหม่) หลังจากป้อนค่าแล้วให้กด Enter เพื่อยุติ
ในการเคลื่อนที่ผ่านองค์ประกอบอาเรย์ เรายังสามารถใช้ for loop ได้ด้วย
for i in “${array[@]}”
do
#access each element as $i. . .
done
สคริปต์ต่อไปนี้สรุปเนื้อหาของส่วนนี้โดยเฉพาะ
#!/bin/bash
array1[0]=one
array1[1]=1
echo ${array1[0]}
echo ${array1[1]}
array2=( one two three )
echo ${array2[0]}
echo ${array2[2]}
array3=( [9]=nine [11]=11 )
echo ${array3[9]}
echo ${array3[11]}
read -a array4
for i in "${array4[@]}"
do
echo $i
done
exit 0
การดำเนินการต่างๆ บนอาร์เรย์
การดำเนินการสตริงมาตรฐานหลายอย่างทำงานบนอาร์เรย์ ดูสคริปต์ตัวอย่างต่อไปนี้ซึ่งใช้การดำเนินการบางอย่างกับอาร์เรย์ (รวมถึงการดำเนินการสตริง)
#!/bin/bash
array=( apple bat cat dog elephant frog )
#print first element
echo ${array[0]}
echo ${array:0}
#display all elements
echo ${array[@]}
echo ${array[@]:0}
#display all elements except first one
echo ${array[@]:1}
#display elements in a range
echo ${array[@]:1:4}
#length of first element
echo ${#array[0]}
echo ${#array}
#number of elements
echo ${#array[*]}
echo ${#array[@]}
#replacing substring
echo ${array[@]//a/A}
exit 0
ต่อไปนี้เป็นผลลัพธ์ที่เกิดจากการรันสคริปต์ด้านบน
apple
apple
apple bat cat dog elephant frog
apple bat cat dog elephant frog
bat cat dog elephant frog
bat cat dog elephant
5
5
6
6
Apple bAt cAt dog elephAnt frog
ฉันคิดว่ามันไม่มีความสำคัญในการอธิบายสคริปต์ข้างต้นโดยละเอียดเนื่องจากเป็นการอธิบายในตัวมันเอง หากจำเป็น ฉันจะอุทิศส่วนหนึ่งในชุดนี้เกี่ยวกับการปรับแต่งสตริงโดยเฉพาะ
การทดแทนคำสั่งด้วยอาร์เรย์
การทดแทนคำสั่งจะกำหนดผลลัพธ์ของคำสั่งหรือหลายคำสั่งไปยังบริบทอื่น ในบริบทของอาร์เรย์นี้ เราสามารถแทรกผลลัพธ์ของคำสั่งเป็นองค์ประกอบแต่ละรายการของอาร์เรย์ได้ ไวยากรณ์มีดังนี้
array=( $(command) )
ตามค่าเริ่มต้น เนื้อหาในเอาต์พุตของคำสั่งที่คั่นด้วยช่องว่างจะถูกเสียบเข้ากับอาร์เรย์เป็นองค์ประกอบแต่ละรายการ สคริปต์ต่อไปนี้แสดงรายการเนื้อหาของไดเร็กทอรีซึ่งเป็นไฟล์ที่มีสิทธิ์ 755
#!/bin/bash
ERR=27
EXT=0
if [ $# -ne 1 ]; then
echo "Usage: $0 <path>"
exit $ERR
fi
if [ ! -d $1 ]; then
echo "Directory $1 doesn't exists"
exit $ERR
fi
temp=( $(find $1 -maxdepth 1 -type f) )
for i in "${temp[@]}"
do
perm=$(ls -l $i)
if [ `expr ${perm:0:10} : "-rwxr-xr-x"` -eq 10 ]; then
echo ${i##*/}
fi
done
exit $EXT
การจำลองอาร์เรย์สองมิติ
เราสามารถแสดงเมทริกซ์ 2 มิติได้อย่างง่ายดายโดยใช้อาเรย์ 1 มิติ ใน แถวลำดับหลัก องค์ประกอบการเป็นตัวแทนในแต่ละแถวของเมทริกซ์จะถูกจัดเก็บอย่างต่อเนื่องในดัชนีอาร์เรย์ในลักษณะตามลำดับ สำหรับเมทริกซ์ mXn สามารถเขียนสูตรสำหรับเมทริกซ์เดียวกันได้เป็น
matrix[i][j]=array[n*i+j]
ดูสคริปต์ตัวอย่างอื่นสำหรับการเพิ่ม 2 เมทริกซ์และพิมพ์เมทริกซ์ผลลัพธ์
#!/bin/bash
read -p "Enter the matrix order [mxn] : " t
m=${t:0:1}
n=${t:2:1}
echo "Enter the elements for first matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read x[$(($n*$i+$j))]
done
done
echo "Enter the elements for second matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read y[$(($n*$i+$j))]
z[$(($n*$i+$j))]=$((${x[$(($n*$i+$j))]}+${y[$(($n*$i+$j))]}))
done
done
echo "Matrix after addition is"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
echo -ne "${z[$(($n*$i+$j))]}\t"
done
echo -e "\n"
done
exit 0
แม้ว่าจะมีข้อจำกัดในการใช้อาร์เรย์ภายในเชลล์สคริปต์ แต่ก็มีประโยชน์ในบางสถานการณ์ โดยเฉพาะอย่างยิ่งเมื่อเราจัดการกับการทดแทนคำสั่ง เมื่อมองจากมุมมองของผู้ดูแลระบบ แนวคิดของอาร์เรย์ได้ปูทางไปสู่การพัฒนาสคริปต์พื้นหลังจำนวนมากในระบบ GNU/Linux