====== AWK ====== >> เนื้อหาส่วนนี้เป็นส่วนหนึ่งของวิชา [[:204223-52|Practicum in Computer Engineering]] [[http://en.wikipedia.org/wiki/AWK|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'' ===== อ่านเพิ่มเติม ===== * [[http://cholwich.org/wordpress/2008/07/05/awk/|บทความ AWK ภาษาไทย]] จากบล็อก Cholwich * [[http://en.wikipedia.org/wiki/AWK|วิกิพีเดีย (อังกฤษ)]] * [[http://awk.info/|AWK community portal]] ที่มีตัวอย่าง[[http://awk.info/?awk1line|การใช้ awk แบบหนึ่งบรรทัด]]มากมาย