AWK

เนื้อหาส่วนนี้เป็นส่วนหนึ่งของวิชา Practicum in Computer Engineering

AWK เป็นภาษาโปรแกรมและเครื่องมือในการประมวลผลข้อความ เราจะหัดใช้ AWK อย่างง่าย ๆ โดยพิจารณาจากตัวอย่าง

ตัวคั่นและการพิมพ์

เราสามารถสั่งให้ awk ทำงานในลักษณะคล้าย ๆ กับคำสั่ง cut ได้ โดยระบุตัวคั่นระหว่างฟิลด์ด้วย option -F (ถ้าไม่ระบุจะถือว่าเป็นช่องว่าง) และอ้างถึงแต่ละฟิลด์ด้วยตัวแปร $1, $2, เป็นต้น (ส่วนตัวแปร $0 จะแทนบรรทัดทั้งบรรทัด)

ยกตัวอย่างเช่น ถ้าเรามีแฟ้ม /etc/password ดังนี้

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh

และเราต้องการพิมพ์ username กับ home directory เราจะสั่ง

awk -F: '{ print $1, $6 }' /etc/passwd

และได้ผลลัพธ์เป็น

root /root
daemon /usr/sbin
bin /bin
sys /dev
sync /bin
games /usr/games
man /var/cache/man
lp /var/spool/lpd

อาร์กิวเมนต์ตัวสุดท้ายคือไฟล์ที่ต้องการประมวลผล (ใส่ได้หลายไฟล์) หรืออาจจะส่งข้อมูลให้โดยการ redirection ก็ได้

อาร์กิวเมนต์ { print $1, $6 } ที่เราส่งให้กับโปรแกรม AWK คือโปรแกรมสำหรับประมวลผล ซึ่งจะประกอบไปด้วยคู่ของ pattern และ action ในลักษณะดังนี้

pattern { action }

โดย action จะทำงานเมื่อบรรทัดที่อ่านเข้ามาตรงกับ pattern ในกรณีที่ไม่ระบุ pattern ก็จะทำงานกับทุก ๆ บรรทัด

:-) แบบฝึกฟัด 5.1 แฟ้ม twocols ประกอบไปด้วยข้อมูลแบบตัวเลขบรรทัดละสองจำนวน เขียนคำสั่ง 1 บรรทัด ที่แสดงข้อมูลจากแฟ้มดังกล่าวที่สลับคอลัมน์แรกกับคอลัมน์ที่สอง

เรียงชื่อแบบสุ่ม

AWK มีฟังก์ชันที่เราสามารถเรียกใช้ได้มากมาย (สามารถดูได้โดยสั่ง man awk) หนึ่งในนั้นคือฟังก์ชัน rand() คำสั่งด้านล่างพิมพ์รายการรหัสประจำตัวจากแฟ้ม sel-id เรียงลำดับแบบสุ่ม

awk '{print rand(), $1}' sel-id | sort -n | cut -d ' ' -f2
:-) แบบฝึกหัด 5.2 อธิบายการทำงานของคำสั่งข้างต้นคร่าว ๆ

คำสั่งดังกล่าวสามารถนำมาดัดแปลงเพื่อแบ่งกลุ่มนิสิตออกเป็นกลุ่มย่อย ๆ 5 กลุ่มแบบสุ่ม โดยผลลัพธ์ที่ต้องการมีลักษณะดังนี้

49054869,1
49552987,1
49055338,1
...
49055338,1
49552052,2
49554967,2
...

นั่นคือมีรายชื่อนิสิต เรียงตามกลุ่มที่สุ่มแล้ว ไม่จำเป็นที่แต่ละกลุ่มจะต้องมีจำนวนนิสิตเท่ากัน (แต่ถ้าเป็นการจัดกลุ่มแบบสุ่มจำนวนคนจะใกล้เคียงกัน)

:-) แบบฝึกหัด 5.3 เขียนคำสั่งเพื่อจัดกลุ่มนิสิตดังกล่าว (ใช้เลขประจำตัวจากไฟล์ sel-id)

คำใบ้: ใช้ฟังก์ชัน int เพื่อปัดเศษ

ตัวแปรและรูปแบบ (pattern)

สำหรับ pattern ที่ใช้ตรวจสอบเงื่อนไขของบรรทัดเพื่อเข้าทำงานใน action นั้น อาจเป็น BEGIN (ทำเมื่อเริ่ม), END (ทำเมื่อสิ้นสุด), หรือเป็นเงื่อนไขก็ได้ เราสามารถระบุเงื่อนไขเป็น regular expression ซึ่งจะเป็นจริงถ้าบรรทัดนั้นมี expression นั้น หรืออาจระบุการทดสอบกับตัวแปรก็ได้ เช่น pattern ว่า $1 ~ /[a-z]+/ ทดสอบว่าฟิลด์แรกมีแค่ตัวอักษร a - z เท่านั้น

คำสั่งด้านล่างนับจำนวนนิสิตใน sel-id แยกเป็นนิสิตภาคปกติกับภาคพิเศษ

awk 'BEGIN { n=0; s=0; } /^4905/ { n++; } /^4955/ { s++; } END { print n,s }' sel-id

สังเกตว่าโปรแกรมด้านล่างเริ่มจะยาว เราสามารถเก็บโปรแกรมลงในแฟ้มก่อน แล้วค่อยเรียกใช้ได้ โดยใช้ option -f โปรแกรมข้างต้นเขียนให้อ่านง่ายขึ้นได้ดังนี้

BEGIN { n=0; s=0; } 
/^4905/ { n++; } 
/^4955/ { s++; } 
END { print n,s }

ถ้าเราเก็บโปรแกรมดังกล่าวในแฟ้มชื่อ countstd เราจะเรียกใช้โดยสั่ง awk -f countstd sel-id

อ่านเพิ่มเติม

204223-52/awk.txt · Last modified: 2009/06/22 05:04 by jittat
 
 
©2008 Another cool website by 80KV