AwkForDummy

จาก Wiki Opensource

ดูแลโดย KX

awk :: คำสั่งบน Unix เป็น pattern scanning and processing language

เช่น เมื่อต้องการดู mail queue เราใช้คำสั่ง mailq จะได้ผลอย่างนี้

CDA5EC684E7     8300 Tue Mar  3 01:07:49  MAILER-DAEMON
(delivery temporarily suspended: connect to alt4.gmail-smtp-in.l.google.com[209.85.220.69]: Connection timed out)
                                         ziddubounces@gmail.com

C215FC68291     3792 Sun Mar  1 09:25:38  MAILER-DAEMON
     (connect to sitemail.everyone.net[216.200.145.235]: Connection timed out)
                                         ggktqojdb@masterwinemaker.com

CCF8BC688FE     3567 Sat Feb 28 17:15:15  MAILER-DAEMON
           (connect to smtp2.gentiva.com[12.108.130.58]: Connection timed out)
                                         pane@gentiva.com

CDB6EC686DB     3849 Sat Feb 28 00:19:27  MAILER-DAEMON
       (connect to ciclon.armada.mil.co[190.24.128.167]: Connection timed out)
                                         czoimpatience@armada.mil.co<br>

หากเราต้องการดู ฟิลด์ หรือ Column แรก ให้ใช้คำสั่ง

# mailq | awk '{print $1}'

แต่จะเห็นว่า ข้อมูลที่ได้จาก mailq มีการขึ้นบรรทัดใหม่ในแต่ละ Record ซึ่งทำให้การ grep ธรรมดา ทำไม่ได้

เช่นสมมุติ เราต้องการเลือกเฉพาะบรรทัดที่มี ฟิลด์ที่ 8 ซึ่งอยู่ต่อท้ายคำว่า MAILER-DAEMON ซึ่งขึ้นบรรทัดใหม่

เป็นคำว่า delivery ให้ทำตามนี้

 mailq | awk '{RS=""};{if ($8 ~ /delivery/){ print $1} }'
  • ให้ใช้คำสั่ง RS = "" ร่วมด้วย จะทำให้ Record Separater (RS) เป็น "" แทน
  • เงื่อนไข if ( $8 ~ /delivery/) {print $1} คือ หากฟิลด์ที่ 8 มีคำว่า delivery แล้ว ให้พิมพ์ ฟิลด์ที่ 1 ออกมา


แต่หากต้องการหา ตรงไหนก็ได้ใน Record ให้ใช้ตัว $0 แทนครับ เช่น

 mailq | awk '{RS=""};{if ($0 ~ /Connection timed out/){ print $1} }'

ได้ทันทีเลย

การจับเอาเฉพาะ field สุดท้าย ในกรณีที่แต่ละ record มี field ไม่เท่ากัน

ใน awk มีคำสั่ง

    NR = Number of Records สำหรับบอกว่า ในไฟล์นี้ มีกี่ Record

    NF = Number of Fields สำหรับบอกว่า ใน Record นี้มีกี่ Field

ดังนั้น หากเรามีไฟล์ ซึ่งมีหลายๆ record ซึ่งแต่ละ record มี fields ไม่เท่ากัน แต่เราต้องการเอา field สุดท้ายออกมา ให้ใช้คำสั่งนี้

awk '{ print $NF }' some-file.txt

แต่หากต้องการ เอา field รองสุดท้าย ก็สามารถใช้คำสั่ง

 awk '{ print $(NF -1 ) }' some-file.txt