สอนเขียน shellscript ตอนที่ 3 อาเรย์มาแล้วจ้าาา

บทความนี้อยู่ในกลุ่มของบทความสอนเขียน shell script ซึ่ง shell script ที่จะสอนนั้นจะใช้ bash เป็น intepreter หรือตัวแปลภาษาครับ

บทความตอนที่แล้ว ผมได้กล่าวถึงการดำเนินการกับข้อมูล ชนิด ตัวเลข และสตริงไปแล้ว ในบทความนี้ผมจะได้กล่าวถึง ชนิดข้อมูลอีกตัวนั่นคือ อาเรย์ ครับ

ข้อมูลชนิดอาเรย์ใน bash หมายถึงโครงสร้างข้อมูลที่ใช้เก็บข้อมูลแบบลำดับการจัดเก็บข้อมูลในอาเรย์มี 2 วิธี

  • วิธีแรกกำหนดครั้งเดียวพร้อมกันหลายตัว โดยระบุสมาชิกภายใต้เครื่องหมายวงเล็บ ( ) แยกสมาชิกแต่ละตัวด้วยช่องว่าง
  • วิธีที่สองระบุผ่านตำแหน่งข้อมูลในอาเรย์ทีละตัวภายใต้เครื่องหมาย [ ]

การอ้างถึงข้อมูลเมื่อต้องการประมวลผล ใช้การระบุตำแหน่งที่จัดเก็บภายใต้เครื่องหมาย ${ } เช่น อาเรย์ a ตำแหน่งที่ 0 เมื่อต้องการอ้างถึงโดยใช้ ${ a[0] }  หากระบุ @ หรือ * แทนใน [] จะหมายถึงข้อมูลทุกตัวในอาเรย์ และขนาดของอาเรย์จะแทนด้วย ${ #a[@] }

ตัวอย่างการจัดเก็บข้อมูลในอาเรย์แบบที่ 1
fruit=( “Apple”   “Pie”    “Orange”   “Coconut” )

ตัวอย่างการจัดเก็บข้อมูลชุดเดียวกันในอาเรย์แบบที่ 2
fruit[0]=”Apple”
fruit[1]=”Pie”
fruit[2]=”Orange”
fruit[3]=”Coconut”

ตัวอย่างการแสดงผลข้อมูลในอาเรย์ทีละตัว

echo “ผลไม้ลำดับที่ 1 คือ ${fruit[0]}  ” ; 
echo “ผลไม้ลำดับสุดท้ายคือ ${fruit[3]}”

ผลลัพธ์จากคำสั่งด้านบนเป็นดังนี้ครับ

ผลไม้ลำดับที่ 1 คือ Apple
ผลไม้ลำดับสุดท้ายคือ Coconut

ลองสังเกตคำสั่งและผลลัพธ์ของคำสั่งต่อไปนี้นะครับ

echo ${ fruit[3] }  
Coconut

echo ${ fruit[@] }  
Apple  Pie  Orange  Coconut

echo ${ #fruit[@]}
4

อาเรย์ของ bash สามารถกำหนดข้อมูลต่างชนิดกันได้
เนื่องจากตัวแปรของ bash เป็นแบบ untype คือไม่ระบุชนิดข้อมูลคงตัวให้กับตัวแปร(ยกเว้นเมื่อกำหนดด้วยคำสั่ง declare ซึ่งจะขอกล่าวถึงในโอกาสถัดไป)  ลักษณะดังนี้จึงถูกสืบทอดมาให้กับโครงสร้างข้อมูลชนิดอาเรย์ด้วย  ตัวอย่างต่อไปนี้ผมลองใช้อาเรย์ BOOK เก็บข้อมูล ชื่อหนังสือ รหัส ISBN และ ราคาของหนังสือตามลำดับ

BOOK=(“Harry Potter”  90011234   256.35 )
echo  “ชื่อหนังสือ : ${BOOK[0]}”
echo  “ISBN : ${BOOK[1]}”
echo  “ราคาปก : ${BOOK[2]} บาท”

ผลลัพธ์จากคำสั่งด้านบนครับ

ชื่อหนังสือ : Harry Potter
ISBN : 90011234
ราคาปก : 256.35 บาท

อาเรย์ของ bash สามารถขยายขนาดได้
ลักษณะที่ยืดหยุ่นอีกประการหนึ่งของอาเรย์ ใน bash คือการที่สามารถขยายขนาดได้ ทำให้เราสามารถนำไปใช้ในงานที่หลากหลายมากขึ้นครับ ขอยกตัวอย่างจากอาเรย์ BOOK ข้างบน ผมจะเพิ่มหนังสืออีก 2 เล่มเข้าไปครับ

BOOK2=(“JAVA Programming” 90012346  350.00)
BOOK3=(“Bash Tutorial” 90056789 1250.50)
BOOK=( ${BOOK[@]}  ${BOOK2[@]}  ${BOOK3[@]} )

ในที่นี้ถ้าเรา ใช้คำสั่ง echo ${#BOOK[@]} จะได้ขนาดเป็น 9 และถ้าใช้คำสั่ง echo ${BOOK[@]} จะเห็นว่าข้อมูลของ BOOK2 และ BOOK3 ถูกนำมารวมไว้ในอาเรย์ BOOK ครับ

echo ${BOOK[@]}
Harry Potter 9000112 235.30 JAVA Programming 90012346 350.00 Bash Tutorial 90056789 1250.50

อาเรย์ใน bash มีแค่มิติเดียว
ข้อจำกัดอย่างหนึ่งของอาเรย์ใน bash คือเราไม่สามารถกำหนดนำอาเรย์มากำหนดให้กับอาเรย์(ฟังแล้วงงใช่ไหมครับ)  ซึ่งก็คือเราไม่สามารถใช้งานในลักษณะของอาเรย์ 2 มิติขึ้นไปได้ ครับ

Animal[0]=(“Dog” “Cat” “Pig”)   
bash: animal[0]: cannot assign list to array member 

 

ผมขอจบเรื่องข้อมูลชนิดอาเรย์ไว้เพียงเท่านี้ก่อน สำหรับบทความตอนหน้าผมจะมากล่าวถึงการเริ่มต้นเขียนสคริปต์ไฟล์ครับ

Advertisements

คำสั่ง echo มีอะไรมากกว่าที่คุณคิด

คำสั่ง echo ที่แสนธรรมดา ในโปรแกรม terminal สามารถให้การแสดงผลที่แตกต่างได้ด้วย escape character ครับ

echo -e คือการแสดงผลข้อความโดยแปลความหมายของ escape character
echo -n หมายถึงไม่ต้องขึ้นบรรทัดใหม่
echo -ne หมายถึงให้แปลความหมายของ escape character โดยไม่ต้องขึ้นบรรทัดใหม่

ตัวอย่าง escape character ที่นิยมใช้ได้แก่
\t หมายถึง tab
\n หมายถึง ขึ้นบรรทัดใหม่


[ ภาพตัวอย่างการใช้งาน echo -ne ]

ยังมี escape character อีกตัวที่เป็นตัวละครลับที่ทำให้การแสดงผลข้อความบนหน้าจอเป็นสีได้
นั่นคือ \e

ตัวอย่างผลลัพธ์การแสดงผลที่เป็นสี

รูปแบบการใช้งาน escape character \e

echo -e “\e[รหัสสีตัวอักษร\e[รหัสสีตัวพื้นหลัง <ข้อความ> \e[0m”

โดยรหัสสีตัวอักษรมีดังนี้
m = สีขาว
31m = สีแดง
32m = สีเขียว
33m = สีน้ำเงิน
34m = สีชมพู
35m = สีฟ้า

ถ้าห้อย 1 มาด้วยจะเป็นตัวหนา
1m = สีขาวตัวหนา
1;31m = สีแดงตัวหนาเป็นต้น

รหัสสีพื้นหลัง
40m – 47m (ไม่รู้จะอธิบายสีว่าอย่างไรครับดูที่ตัวอย่างแล้วกัน)

ค่าซ้ายมือคือค่ารหัสสีของตัวอักษร ส่วนค่าที่อยู่ด้านบนคือค่าของรหัสสีพื้นหลังครับ : )

เปลี่ยนรูปภาพให้กับโปรแกรม cowsay

ผมเคยกล่าวถึงโปรแกรม cowsay จากบทความ เพิ่ม welcome message เมื่อเปิด terminal  วันนี้ผมขอเพิ่มลูกเล่นอีกนิดโดยการเปลี่ยนรูปภาพการแสดงผลครับ : )

นอกจากรูปงัว(วัว)แล้ว ใน cowsay ยังสามารถกำหนดการแสดงผลเป็นรูปอื่นได้ โดยการเพิ่ม ออฟชั่น -f  ตามด้วยรูปที่ต้องการแสดงผลครับ
ในที่นี้ผมจับภาพหน้าจอ terminal ผมมาโชว์สัก 4 ภาพ

ตัวอย่าง

เอาแค่พอหอมปากหอมคอก่อนแล้วกันครับ ถ้าใครอยากรู้ว่ามีรูปอะไรบ้างสามารถดูได้โดยใช้คำสั่ง cowsay -list ครับ : )

การสร้างไฟล์เปล่า ๆ(ขนาด 0 byte) บน linux

การสร้างไฟล์ขนาด 0 byte บนลีนุกส์มีด้วยกัน 3 วิธีคือ

  1. touch a.txt (ใช้ได้เฉพาะกรณีที่ไม่มีไฟล์อยู่)
  2. :>a.txt   (ใช้ built in ใน bash ไม่มีการ fork )
  3. cat /dev/null > a.txt  


ภาพตัวอย่างการสร้างไฟล์ขนาด 0 byte

ปล. การสร้างไฟล์โดยใช้คำสั่ง echo “” > a.txt จะทำให้ได้ไฟล์ขนาด 1 byte ซึ่งไม่ถือว่าเป็นไฟล์เปล่าครับ : )

สอนเขียน shell script ตอนที่ 2 การดำเนินการกับข้อมูล

บทความนี้อยู่ในกลุ่มของบทความสอนเขียน shell script ซึ่ง shell script ที่จะสอนนั้นจะใช้ bash เป็น intepreter หรือตัวแปลภาษาครับ

จากบทความ ตอนที่ 1  ผมได้จำแนกข้อมูลใน bash ตามค่าของข้อมูลแบ่งออกเป็น 3 กลุ่มคือ  ตัวเลข ข้อความ และอาเรย์ ในบทความนี้ผมจะได้กล่าวถึงการดำเนินการกับตัวแปรหรือข้อมูลในกลุ่มต่าง ๆ ครับ

1 .การดำเนินการกับตัวเลข

bash มีข้อจำกัดในการประมวลผลกับตัวเลขที่เป็นจำนวนเต็มและเป็นการคำนวณง่าย ๆ เท่านั้น ส่วนการประมวลผลตัวเลขที่เป็นจำนวนจริง(ทศนิยม) ไม่สามารถประมวลผลได้โดยตรงรวมถึงการประมวลผลทางคณิตศาสตร์ที่ซับซ้อน แนวทางแก้ไขปัญหานี้คือการใช้งานร่วมกับโปรแกรม  bc  ผ่านกระบวนการ pipeline (ผู้เขียนขอข้ามส่วนนี้ไปก่อน และจะได้กล่าวถึงในบทความถัดไป ) ในที่นี้จะขอกล่าวถึงการประมวลผลตัวเลขที่เป็นจำนวนเต็มเท่านั้น

1.1  การดำเนินการภายใต้เครื่องหมาย Arithemtic Expansion(AE) :  $(( ))
bash จะประมวลผลคำสั่งในเครื่องหมาย AE  โดยมองว่าข้อมูลข้างในเป็นการคำนวณทางคณิตศาสตร์ โดยตัวแปรที่นำมาใช้ภายใต้ AE นั้นสามารถละเครื่องหมาย $ ได้ โดยโอเปอเรชั่นทางคณิตศาสตร์ใน AE นั้นจะคล้ายๆกับ โอเปอเรชั่นทั่วไปในภาษาโปรแกรมอื่น ดังนี้

  • var++ , var–  ,++var, –var     การทำ post-increment  post-decrement  pre-increment และ pre-decrement ตามลำดับ
  • +  –  *  /  %   เครื่องหมายการบวก  การลบ  การคูณ การหาร(ไม่เก็บเศษ) และการหารเก็บเฉพาะเศษ(modulo) ตามลำดับ
  • **  เครื่องหมายยกกำลัง
  • =  +=  -=  *=  /=  %=   การกำหนดค่า การกำหนดค่าหลังจากการบวก ลบ คูณ หาร หารเก็บเศษ ตามลำดับ
  • >>  <<  การเลื่อนบิตขวาและซ้าย ตามลำดับ

ในการใช้สัญลักษณ์ AE เมื่อไม่มีการรีเทิร์นค่าจาก AE ให้ละเครื่องหมาย $

ตัวอย่างการใช้งาน AE

$ a=10  b=20
$ echo $a+$b
10+20
$ echo $((a+b))
30
$ echo $((a**3))
1000
$ echo $(( -b+2*a ))
0
$ (( a++ ))
$ echo $a
11

1.2 การใช้คำสั่ง let
ใน bash จะมีคำสั่งที่เป็น built-in ที่ชื่อ let ซึ่งจะใช้สำหรับจัดการประมวลผลทางคณิตศาสตร์เช่นเดียวกับ AE แต่จะดูง่ายต่อการอ่านมากกว่า การใช้ AE ครับ  ตัวแปรที่ตามหลังคำสั่ง let สามารถละเครื่องหมาย $ ได้เช่นเดียวกัน

ตัวอย่างการใช้คำสั่ง let

$ a=10 b=20
$ let c=b/a
$ echo “$b/$a=$c
20/10=2

2. การดำเนินการกับข้อความ

ข้อความหรือ string ใน bash นั้นถือว่าเป็นข้อมูลพื้นฐาน เนื่องจากข้อมูลส่วนใหญ่ที่เขียนในสคริปต์มักจะอ้างอิงเป็นชื่อโปรแกรมหรือพารามิเตอร์ ซึ่ง bash ได้ให้ความสำคัญกับการจัดการกับข้อมูลชนิดข้อความ มากกว่าการจัดการกับการประมวลผลทางคณิตศาสตร์ครับ

2.1ขนาดของข้อความ

${#string}

ตัวอย่าง
$ a=”Wayne Rooney is a world class footballer.”
$ echo ${#a}
41
$ a=
$ echo ${#a}
0

2.2 การตัดคำ

${string:position}
การตัดคำจากข้อความ string โดยเริ่มจากตำแหน่ง position ที่กำหนด

${string:position:length}
การตัดคำจากข้อความ string โดยเริ่มจากตำแหน่ง position ที่กำหนด โดยระบุความยาวของตัวอักษร

ตัวอย่าง

$ a=”Sir Alex Ferguson”
$ echo ${a:4}
Alex Ferguson
$ echo ${a:4:4}
Alex

2.3 การตัดคำด้วยข้อความ

${string#substring}
ตัดคำด้วยข้อความที่อยู่ด้านหน้า substring  ถ้าใช้ regular expression จะตัดคำโดยใช้รูปแบบที่เข้ากับ pattern ในแบบสั้นที่สุด

${string##substring}
ตัดคำด้วยข้อความที่อยู่ด้านหน้า substring  ถ้าใช้ regular expression จะตัดคำโดยใช้รูปแบบที่เข้ากับ pattern ในแบบยาวที่สุด

${string%substring}
ตัดคำด้วยข้อความที่อยู่ด้านหลัง substring  ถ้าใช้ regular expression จะตัดคำโดยใช้รูปแบบที่เข้ากับ pattern ในแบบสั้นที่สุด

${string%%substring}
ตัดคำด้วยข้อความที่อยู่ด้านหลัง substring  ถ้าใช้ regular expression จะตัดคำโดยใช้รูปแบบที่เข้ากับ pattern ในแบบยาวที่สุด

ตัวอย่าง
$ a=”Dimitar Berbatov”
echo ${a#Dimitar}
Berbatov
echo ${a##Dimitar}
Berbatov
echo ${a#D*r}    #—>   ใช้ #D*r จะ match กับคำว่า Dimitar
Berbatov
echo ${a##D*r} #—>  ใช้  ##D*r จะ match กับคำว่า Dimitar Ber
batov
echo ${a%a*}    #—>   ใช้ %a* จะ match กับคำว่า atov
Dimitar Berb
echo ${a%%a**} #—>  ใช้ %%a* จะ match กับคำว่า ar Berbatov
Dimit

2.4 การค้นหาและแทนที่ข้อความ

${string/substring/replacement}
แทนที่ข้อความตัวแรกที่ match กับค่าของ substring ด้วยค่าของ replacement

${string//substring/replacement}
แทนที่ข้อความทุกตัวที่ match กับค่าของ substring ทุกตัวด้วยค่าของ replacement

${string/#substring/replacement}
ถ้าคำขึ้นต้นของข้อความ  match กับค่าของ substring จะแทนที่ข้อความนั้นด้วยค่า replacement

${string/%substring/replacement}
ถ้าคำลงท้ายของข้อความ  match กับค่าของ substring จะแทนที่ข้อความนั้นด้วยค่า replacement

ตัวอย่าง
$ a=”man who is not a man”
$ echo ${a/man/girl}
girl who is not a man

$ echo ${a//man/girl}
girl who is not a girl

$ echo ${a/#man/girl}
girl who is not a man

$ echo ${a/%man/girl}
man who is not a girl