Table of Contents
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
อ่านเพิ่มเติม
- บทความ AWK ภาษาไทย จากบล็อก Cholwich
- AWK community portal ที่มีตัวอย่างการใช้ awk แบบหนึ่งบรรทัดมากมาย