ค้นหาเว็บไซต์

การทำงานกับอาร์เรย์ใน 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