การใช้ awk บน Linux ตัวอย่างคำสั่ง AWK ใน Linux

ข้อความคือหัวใจของ Unix ปรัชญา "ทุกอย่างเป็นไฟล์" แทรกซึมไปทั่วทั้งระบบและเครื่องมือที่พัฒนาขึ้นสำหรับระบบนั้น นั่นเป็นเหตุผลที่ทำงาน
พร้อมข้อความถือเป็นหนึ่งในทักษะที่จำเป็น ผู้ดูแลระบบหรือผู้ใช้ Linux มือใหม่

AWK เป็นหนึ่งในที่สุด เครื่องมืออันทรงพลังสำหรับการประมวลผลและการกรองข้อความ สามารถเข้าถึงได้แม้กระทั่งผู้ที่ไม่เกี่ยวข้องกับการเขียนโปรแกรมก็ตาม

การใช้ awk บน Linux

งานที่ง่ายที่สุดและใช้บ่อยที่สุดคือการดึงข้อมูลฟิลด์จากเอาต์พุตมาตรฐาน คุณจะไม่พบเครื่องมือที่ดีกว่าสำหรับงานนี้มากกว่า awk ตามค่าเริ่มต้น awk จะแยกฟิลด์ด้วยการเว้นวรรค หากคุณต้องการพิมพ์ฟิลด์แรก คุณเพียงแค่ต้องระบุพารามิเตอร์ $1 ให้กับ awk:

echo "หนึ่ง สอง สาม สี่" | awk "(พิมพ์ $1)"

ใช่ การใช้เหล็กดัดฟันอาจดูแปลกไปสักหน่อย แต่นี่เป็นเพียงครั้งแรกเท่านั้น คุณได้เดาวิธีการพิมพ์ฟิลด์ที่สอง สาม สี่ หรือฟิลด์อื่น ๆ แล้วหรือยัง? ถูกต้องคือ $2, $3, $4 ตามลำดับ

echo "หนึ่ง สอง สาม สี่" | awk "(พิมพ์ $3)"

บางครั้งจำเป็นต้องนำเสนอข้อมูลในรูปแบบเฉพาะ เช่น การเลือกคำไม่กี่คำ AWK จัดการการจัดกลุ่มหลายช่องได้อย่างง่ายดาย และยังช่วยให้คุณสามารถรวมข้อมูลคงที่ได้:

echo "หนึ่ง สอง สาม สี่" | awk "(พิมพ์ $3,$1)"
สามหนึ่ง

echo "หนึ่ง สอง สาม สี่" | awk "(พิมพ์ "foo:",$3,"| บาร์:",$1)"
ฟู: สาม | บาร์:หนึ่ง

หากฟิลด์ถูกคั่นด้วยตัวคั่นอื่นที่ไม่ใช่ช่องว่าง เพียงระบุตัวคั่นที่ต้องการในเครื่องหมายคำพูดในพารามิเตอร์ -F เช่น : : :

echo "หนึ่งมิสซิสซิปปี้: สองมิสซิสซิปปี้: สามมิสซิสซิปปี้: สี่มิสซิสซิปปี้" | awk -F: "(พิมพ์ $4)"
สี่มิสซิสซิปปี้

แต่ไม่จำเป็นต้องใส่ตัวคั่นในเครื่องหมายคำพูด เอาท์พุทถัดไปคล้ายกับอันก่อนหน้า:

echo "หนึ่งมิสซิสซิปปี้: สองมิสซิสซิปปี้: สามมิสซิสซิปปี้: สี่มิสซิสซิปปี้" | awk -F: "(พิมพ์ $4)"
สี่มิสซิสซิปปี้

บางครั้งคุณจำเป็นต้องประมวลผลข้อมูลที่มีจำนวนฟิลด์ที่ไม่รู้จัก หากคุณต้องการเลือกฟิลด์สุดท้าย คุณสามารถใช้ตัวแปร $NF ได้ นี่คือวิธีที่คุณสามารถแสดงฟิลด์สุดท้าย:

echo "หนึ่ง สอง สาม สี่" | awk "(พิมพ์ $NF)"
สี่

คุณยังสามารถใช้ตัวแปร $NF เพื่อรับฟิลด์ที่สองถึงฟิลด์สุดท้าย:

echo "หนึ่ง สอง สาม สี่" | awk "(พิมพ์ $(NF-1))"
สาม

หรือช่องจากตรงกลาง:

echo "หนึ่ง สอง สาม สี่" | awk "(พิมพ์ $((NF/2)+1))"
สาม

echo "หนึ่ง สอง สาม สี่ ห้า" | awk "(พิมพ์ $((NF/2)+1))"
สาม

ทั้งหมดนี้สามารถทำได้โดยใช้โปรแกรมอรรถประโยชน์เช่น sed, cut และ grep แต่จะยากกว่ามาก

และอีกหนึ่งฟีเจอร์ของ awk รองรับตัวจัดการสตริง:

echo -e "หนึ่ง 1\n สอง 2" | awk "(พิมพ์ $1)"
หนึ่ง
สอง

echo -e "หนึ่ง 1\n สอง 2" | awk "(พิมพ์ $2)"
1
2

echo -e "หนึ่ง 1\n สอง 2" | awk "(sum+=$2) END (ผลรวมการพิมพ์)"
3

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

ลองนึกภาพเรามีบันทึกการเข้าถึงที่มีลักษณะดังนี้:

23 ก.ค. 18:57:12 HTTPD: "GET/foo/bar HTTP/1.1" 200,344
23 ก.ค. 18:57:13 HTTPD : "GET/HTTP/1.1" 200 9300
23 ก.ค. 19:01:27 HTTPD : "GET / HTTP / 1.1" 200 9300
23 ก.ค. 19:01:55 HTTPD : "GET / Foo / Baz HTTP / 1.1" 200 6401
23 ก.ค. 19:02:31 HTTPD: "? GET / Foo / Baz page = 2 HTTP / 1.1" 200 6312

เรารู้ว่าฟิลด์สุดท้ายคือจำนวนไบต์ที่ถ่ายโอน จากนั้นเราสามารถใช้ตัวแปร $NF ได้:

< requests.log awk "{print $NF}"
344
9300
9300

วัตถุประสงค์หลักของโปรแกรม โอเค- การตีความภาษาการเขียนโปรแกรม awk ซึ่งช่วยให้คุณสามารถสร้างโปรแกรมสำหรับการวิเคราะห์และการแปลงได้อย่างรวดเร็ว ไฟล์ข้อความ- สคริปต์ awk ทั่วไปมีลักษณะดังนี้:

เทมเพลต 1 (การกระทำ 1) เทมเพลต 2 (การกระทำ 2) ...

โปรแกรมก็อ่าน ไฟล์อินพุตหรือสตรีมและแยกวิเคราะห์แต่ละบรรทัดเพื่อให้ตรงกับรูปแบบ หากมีการแข่งขัน การกระทำที่อธิบายไว้ใน วงเล็บปีกกา- หากไม่มีรูปแบบ การดำเนินการจะถูกนำไปใช้กับแต่ละบรรทัด หากไม่มีการดำเนินการ บรรทัดจะถูกพิมพ์ไปที่ เอาต์พุตมาตรฐาน- การดำเนินการอาจประกอบด้วยลำดับของคำสั่งที่คั่นด้วยเครื่องหมายอัฒภาค

การพิมพ์ฟิลด์ที่สาม (คอลัมน์, คำ) ของแต่ละบรรทัด:

รหัส:

ls -l | awk "(พิมพ์ ($3))"

พิมพ์สองฟิลด์ที่ระบุของแต่ละบรรทัด:

รหัส:

ls -l | awk "(พิมพ์($9,$1))"

ช่องการพิมพ์ที่มีช่องว่าง:

รหัส:

ls -l | awk "(พิมพ์($9," ",$1))"

หากต้องการระบุตัวคั่นฟิลด์อื่นที่ไม่ใช่ช่องว่าง ให้ใช้ตัวเลือก -F ใน ในกรณีนี้ตัวคั่นฟิลด์จะเป็นโคลอน:

รหัส:

Awk -F: "(พิมพ์ ($2))" $filenameForProcessing

หากต้องการใช้สคริปต์ awk ที่บันทึกไว้ในไฟล์:

รหัส:

Awk -f $scriptFilename $filenameForProcessing

ไฟล์สคริปต์ awk สามารถเรียกใช้งานได้และมี sha-bang ที่เกี่ยวข้องระบุไว้ในไฟล์ สคริปต์ดังกล่าวจะใช้ไฟล์สำหรับการประมวลผลเป็นพารามิเตอร์:

รหัส:

#!/usr/bin/awk -f

ตัวแปร awk จะถูกสร้างขึ้นในครั้งแรกที่มีการเข้าถึงและสามารถมีจำนวนเต็ม ทศนิยม หรือสตริง ตามที่กำหนดโดยบริบท ตัวแปรพิเศษ RS เก็บค่าของตัวแยกบันทึก (\n ตามค่าเริ่มต้น) และตัวแปร FS จะเก็บค่าของตัวแยกฟิลด์ (ค่าเริ่มต้น - ช่องว่าง) หากตัวแปรตัวใดตัวหนึ่งมีอักขระมากกว่าหนึ่งตัว ค่านั้นจะถูกตีความว่าเป็นนิพจน์ทั่วไป ภาษา awk มีสตริงในตัวจำนวนหนึ่งและ ฟังก์ชันทางคณิตศาสตร์, คำสั่งแบบมีเงื่อนไขและตัวดำเนินการวนซ้ำ รองรับอาร์เรย์และคำจำกัดความ ฟังก์ชั่นที่กำหนดเอง- คุณสามารถค้นหาได้บนอินเทอร์เน็ต คำแนะนำที่กว้างขวางในภาษา awk เช่นเดียวกับนักแปลอัตโนมัติ (“นักแปล”) ของสคริปต์ awk เป็นภาษาอื่น (เช่น C หรือ Perl)

รูปแบบพิเศษคือ BEGIN และ END พวกเขาจะไม่ถูกตรวจสอบกับรายการสตรีมอินพุต การดำเนินการรูปแบบ BEGIN จะดำเนินการหนึ่งครั้งก่อนที่จะอ่านข้อมูลอินพุต และการดำเนินการรูปแบบ END จะดำเนินการหนึ่งครั้งหลังจากอ่านข้อมูลอินพุตแล้ว

ตัวอย่างการลบบรรทัดที่ซ้ำกันที่อยู่ติดกันในไฟล์:

รหัส:

ชื่อไฟล์=test.txt
res=`awk "BEGIN (PREV="") (ถ้า ($0 != PREV) (พิมพ์ $0; PREV=$0))" $filename`
เสียงก้อง "$res"> $filename

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

ตัวอย่างการต่อข้อมูลฟิลด์:

รหัส:

Awk "(a = $3 $4; พิมพ์ a)" $filename

ตัวอย่างค่าฟิลด์ผลรวม:

รหัส:

Awk "(a = $3+$4; พิมพ์ a)" $filename

ควรเข้าใจแนวคิดของ "ตัวเลือก" ว่าเป็นส่วนขยายของแนวคิด "เทมเพลต" เมื่อมีการระบุรูปแบบในโครงสร้างคำสั่ง โดยทั่วไป ตัวเลือกใดๆ ก็สามารถปรากฏขึ้นได้

ทดสอบฟิลด์ที่สามกับนิพจน์ทั่วไปและพิมพ์ทั้งบรรทัดหากสำเร็จ:

รหัส:

Awk "$3~/(7)$/ (พิมพ์)" $filename

ตรวจสอบฟิลด์แรกเพื่อความเท่าเทียมกันกับสตริงที่ระบุ และพิมพ์ฟิลด์ที่สองหากสำเร็จ

ในบทความที่ฉันวางแผนจะแบ่งปัน ตัวอย่างที่เป็นประโยชน์ซึ่งช่วยให้ฉันแก้ปัญหาในชีวิตประจำวันและทำให้การใช้บรรทัดคำสั่งง่ายขึ้นมาก สำหรับผู้ที่ยังไม่คุ้นเคยกับ AWK ฉันขอแนะนำให้คุณเชี่ยวชาญภาษาสคริปต์นี้อย่างแน่นอน ไม่มีอะไรซับซ้อนเกี่ยวกับมัน ฉันวางแผนที่จะแนบแต่ละตัวอย่างพร้อมความคิดเห็นเล็กๆ น้อยๆ ที่ให้ความกระจ่างเกี่ยวกับความแตกต่างของการใช้โอเปอเรเตอร์บางตัว
.

เรากำลังมองหาบรรทัดที่มีพารามิเตอร์ ผูกที่อยู่ในไฟล์กำหนดค่า

root@debian:~# awk '/bind-address/' /etc/mysql/my.cnf
ที่อยู่ผูก = 127.0.0.1
ที่อยู่ผูก = 192.168.1.110

คำอธิบาย: AWK มีไวยากรณ์และตัวเลือกต่อไปนี้

โอเค[-f program_file | 'โปรแกรม'] [-Fdelimiter]
[-v ตัวแปร = ค่า] [ไฟล์ ... ]

-ฉค่า — กำหนดตัวคั่น (ตั้งค่าของตัวแปร FS ในตัว)
−ฉไฟล์ - ข้อความโปรแกรมถูกอ่านจากไฟล์ แทนที่จะเป็นบรรทัดคำสั่ง รองรับการอ่านจากหลายไฟล์
−v var=value - กำหนดค่าที่ต้องการให้กับตัวแปร
−− — เป็นจุดสิ้นสุดของรายการตัวเลือก

ตัวอย่างหมายเลข 2

ในตัวอย่างข้างต้น การค้นหาเสร็จสิ้นในไฟล์ แต่ AWK ก็สามารถยอมรับเอาต์พุตของคำสั่งอื่นได้เช่นกัน ลองทำให้ตัวอย่างของเราซับซ้อนตามนั้น

root@debian-wordpress:~# แมว /etc/mysql/my.cnf | awk '/ ผูกที่อยู่/'
ที่อยู่ผูก = 127.0.0.1
ที่อยู่ผูก = 192.168.1.110

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

ตัวอย่างหมายเลข 3

รายการ ลิงก์สัญลักษณ์และเส้นทางไปยังไฟล์สุดท้าย

root@debian:~# ls -l /bin/ | awk '/lrwxrwxrwx/ (พิมพ์ $9, $10, $11)'
bzcmp -> bzdiff
bzegrep -> bzgrep
bzfgrep -> bzgrep
bzless -> bzmore
ไฟล์น้อย -> lesspipe
lsmod -> kmod
mt -> /etc/ทางเลือก/mt
nc -> /etc/ทางเลือก/nc
netcat -> /etc/alternatives/netcat
เปิด -> openvt
pidof -> /sbin/killall5
ทุบตี -> ทุบตี
นาโน -> นาโน
ช -> เส้นประ
sh.distrib -> เส้นประ

คำอธิบาย: โปรแกรม awk เป็นคู่เทมเพลต ( ลวดลาย) และการกระทำ ( (การกระทำ)) รวมถึงคำจำกัดความของฟังก์ชันที่ผู้ใช้กำหนด รูปแบบและการกระทำมี มุมมองถัดไป: รูปแบบ (การกระทำ) เทมเพลตหรือการดำเนินการสามารถละเว้นได้ ในกรณีแรกการดำเนินการจะดำเนินการในแต่ละบรรทัด ในกรณีที่สอง จะดำเนินการเอาต์พุตปกติไปยังหน้าจอ เทียบเท่ากับคำสั่ง(พิมพ์)- เหล่านี้ คำหลักไม่สามารถใช้ร่วมกับเทมเพลตอื่นได้.

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

ตัวอย่างหมายเลข 4

จากข้อมูลข้างต้น มาดูตัวอย่างการเปลี่ยนตัวคั่นเริ่มต้น - ดูรายชื่อผู้ใช้ทั้งหมดที่ไม่มีข้อมูลเพิ่มเติม

root@debian:~# awk -F ซิลิโคน '( พิมพ์ $1 )' /etc/passwd
ราก
ภูต
ถังขยะ
ระบบ
ซิงค์
เกม
ผู้ชาย

(เอาต์พุตคำสั่งสั้นลง)

คำอธิบาย: เนื่องจากอยู่ในไฟล์ /etc/passwdบันทึกจะถูกจัดเก็บในรูปแบบ " รูท:x:0:0:root:/root:/bin/bash" การเลือกโคลอนเป็นตัวคั่นและแสดงฟิลด์แรกสุดนั้นค่อนข้างสมเหตุสมผล ( $1 ) แต่ละบรรทัด ( $0 ).

ตัวอย่างหมายเลข 5

ทั้งหมดในไฟล์เดียวกันกับผู้ใช้ คุณสามารถนับจำนวนของพวกเขาได้

root@debian:~# awk 'END ( พิมพ์ NR )' /etc/passwd
25

คำอธิบาย: เทมเพลตพิเศษ เริ่มและ จบสามารถใช้ควบคุมก่อนอ่านบรรทัดอินพุตแรกและหลังจากอ่านบรรทัดอินพุตสุดท้ายตามลำดับ

Awk เป็นหลัก ตัวแก้ไขสตรีมมิ่งเหมือนเซด คุณสามารถไพพ์ข้อความลงในโปรแกรมนี้และสามารถจัดการทีละบรรทัดได้ โปรแกรมยังสามารถอ่านจากไฟล์ได้ Awk ก็เป็นภาษาโปรแกรมเช่นกัน โดยพื้นฐานแล้วหมายความว่า awk สามารถทำทุกอย่างที่ sed ทำได้และอีกมากมาย

awk ต่างจาก sed ตรงที่สามารถจำบริบท ทำการเปรียบเทียบ และอื่นๆ อีกมากมายที่ภาษาโปรแกรมอื่นสามารถทำได้ ตัวอย่างเช่น ไม่จำกัดเพียงบรรทัดเดียว ด้วยทักษะที่เหมาะสม มันสามารถเชื่อมต่อหลายบรรทัดได้

ที่สุด รูปแบบที่เรียบง่าย awk มีลักษณะดังนี้:

แย่ "(some_action ที่นี่)"

"Some_action_here" อาจเป็นเพียงนิพจน์สำหรับพิมพ์ผลลัพธ์ หรือสิ่งที่ซับซ้อนกว่านั้นมาก ไวยากรณ์คล้ายกับภาษาโปรแกรม "C" ตัวอย่างง่ายๆ:

แย่ "(พิมพ์ $1,$3)"

หมายถึงการพิมพ์คอลัมน์ที่หนึ่งและสาม โดยที่คอลัมน์หมายถึง "สิ่งที่คั่นด้วยช่องว่าง" ช่องว่าง = แท็บหรือช่องว่าง

ตัวอย่างสด:

ก้อง "1 2 3 4" | awk "(พิมพ์ $1,$3)" 1 3

ส่วนที่สอง: AWK ทำอะไรได้บ้าง

จุดประสงค์หลักในชีวิตของ AWK คือการจัดการอินพุตทีละบรรทัด โปรแกรม awkมักจะทำงานอย่างมีสไตล์

หากสิ่งที่คุณต้องการทำไม่เข้ากับโมเดลนี้ awk อาจไม่เหมาะกับแนวคิดของคุณ

ไวยากรณ์ปกติที่ใช้ในการเขียนโปรแกรม awk สามารถอธิบายได้ดังต่อไปนี้:

ตัวอย่าง Awk (คำสั่ง)

มันหมายความว่าอย่างนั้น

“ดูแต่ละบรรทัดของอินพุตเพื่อดูว่ามี PATTERN อยู่ที่นั่นหรือไม่ หากมีให้เรียกใช้สิ่งที่อยู่ระหว่าง ()"

คุณสามารถข้าม SAMPLE หรือ COMMAND ได้

ถ้าคุณไม่ระบุรูปแบบ คำสั่งจะถูกนำไปใช้กับทุกบรรทัด

หากละเว้นคำสั่ง นี่จะเทียบเท่ากับการระบุ (เพียงพิมพ์บรรทัด):

(พิมพ์)

ตัวอย่างเฉพาะ:

Awk "/#/ (พิมพ์ "มีความคิดเห็นในบรรทัดนี้")" /etc/hosts

จะพิมพ์ "บรรทัดนี้มีความคิดเห็น" สำหรับทุกบรรทัดที่มีอย่างน้อยหนึ่ง "#" ที่ใดก็ได้บนบรรทัดใน /etc/hosts

ปรับเปลี่ยนเพื่อความชัดเจน

Awk "/#/ (พิมพ์ $0 ":\tมีความคิดเห็นในบรรทัดนี้)" /etc/hosts

องค์ประกอบ "//" ในรูปแบบเป็นวิธีหนึ่งในการระบุการจับคู่ ยังมีวิธีอื่นๆ ในการพิจารณาว่าสตริงตรงกันหรือไม่ ตัวอย่างเช่น,

Awk "$1 == "#" (พิมพ์ "บรรทัดขึ้นต้นด้วยแฮช")" /etc/hosts

จะจับคู่แถวที่มีคอลัมน์แรกเป็น "#" เดียว ลำดับของอักขระ "==" หมายถึงการจับคู่ที่ตรงกันของคอลัมน์แรกทั้งหมด

การปรับเปลี่ยนเพื่อความชัดเจน:

Awk "$1 == "#" (พิมพ์ $0 "\tline เริ่มต้นด้วยแฮช)" /etc/hosts

ในทางกลับกัน หากคุณต้องการให้คอลัมน์ใดคอลัมน์หนึ่งตรงกันบางส่วน ให้ใช้ตัวดำเนินการ "~"

Awk "$1 ~ /#/ (พิมพ์ "บางแห่งมีแฮชในคอลัมน์ 1")" /etc/hosts

โปรดจำไว้ว่าคอลัมน์แรกอาจอยู่หลังพื้นที่สีขาว

การปรับเปลี่ยนเพื่อความชัดเจน:

Awk "$1 ~ /#/ (พิมพ์ $0 "\t มีแฮชอยู่ที่ไหนสักแห่งในคอลัมน์ 1)" /etc/hosts

การป้อน "ความคิดเห็น" จะตรงกัน

การป้อน "ความคิดเห็น" จะตรงกันด้วย

หากคุณต้องการการจับคู่เฉพาะของ "สตริงที่ขึ้นต้นด้วย # และช่องว่าง" คุณจะใช้

อ๊ากก "/^#/ (ทำอะไรสักอย่าง)"

การแข่งขันหลายรายการ

Awk จะประมวลผลตัวอย่างทั้งหมดที่ตรงกัน เส้นปัจจุบัน- ดังนั้นหากเราใช้ตัวอย่างต่อไปนี้

Awk " /#/ (พิมพ์ "มีความคิดเห็น") $1 == "#" (พิมพ์ "ความคิดเห็นในคอลัมน์แรก") /^# / (พิมพ์ "ความคิดเห็นตั้งแต่เริ่มต้น") " /etc/hosts

สามรายการจะถูกส่งออกสำหรับบรรทัดดังต่อไปนี้:

#นี่คือความคิดเห็น

สองรายการสำหรับ

#นี่คือความคิดเห็นเยื้อง

และเพียงหนึ่งเดียวสำหรับ

1.2.3.4 ชื่อโฮสต์ # ความคิดเห็นสุดท้าย

การติดตามบริบท

สตริงทั้งหมดไม่ได้ถูกสร้างขึ้นเท่ากัน แม้ว่าจะดูเหมือนกันก็ตาม บางครั้งคุณอาจต้องการทำอะไรบางอย่างกับสตริงโดยขึ้นอยู่กับบรรทัดที่อยู่ข้างหน้า

ที่นี่ ตัวอย่างด่วนซึ่งพิมพ์บรรทัด "ADDR" หากคุณไม่ได้อยู่ในส่วน "ความลับ"

Awk " /secretstart/ ( secret=1) /ADDR/ ( if(secret==0) print $0 ) /* $0 คือ เต็มบรรทัด*/ /secretend/ ( ความลับ=0) "

ข้อมูลต่อไปนี้จะพิมพ์เนื้อหาที่มี "ADDR" อยู่ข้างใน เว้นแต่จะเห็นสตริง "secretstart" เรื่องการสั่งซื้อ เช่น ถ้าคุณเขียนแบบนี้:

Awk " /ADDR/ ( if(secret==0) print $0 ) /* $0 เป็นบรรทัดที่สมบูรณ์ */ /secretstart/ ( Secret=1) /secretend/ ( Secret=0) "

และป้อนข้อมูลต่อไปนี้

ADDR addr ปกติ ลับเริ่ม ADDR addr ลับ ADDR ความลับอื่น addr ADDR ลับที่สาม ลับ ADDR ปกติด้วย

จากนั้น addr "ลับ" อันแรกจะถูกพิมพ์ เนื่องจากตัวอย่างดั้งเดิมจะซ่อนความลับไว้ทั้งสองอย่าง

ส่วนที่ 3: ตัวแปรพิเศษ

เราได้พูดคุยเกี่ยวกับไวยากรณ์ awk ตามปกติแล้ว ตอนนี้เรามาเริ่มดูสิ่งที่ทันสมัยกันดีกว่า

awk มีสตริงการจับคู่ "พิเศษ": " เริ่ม" และ " จบ"

คำสั่ง เริ่มเรียกหนึ่งครั้งก่อนที่จะอ่านแถวใดๆ จากข้อมูล และจะไม่เรียกอีกครั้ง

คำสั่ง จบเรียกว่าหลังจากอ่านทุกบรรทัดแล้ว หากได้รับหลายไฟล์ ระบบจะเรียกใช้หลังจากไฟล์ล่าสุดเสร็จสมบูรณ์แล้วเท่านั้น

โดยปกติแล้วคุณจะใช้ เริ่มสำหรับการเริ่มต้นที่แตกต่างกัน และ จบเพื่อสรุปหรือทำความสะอาด

BEGIN ( maxerrors=3 ; logfile=/var/log/something ; tmpfile=/tmp/blah) ... ( blah blah blah ) /^header/ ( headercount += 1 ) END ( printf("total headers counted=% d\n", จำนวนส่วนหัว);

ตัวอย่างนี้จะนับจำนวนครั้งที่ "ส่วนหัว" ปรากฏในไฟล์อินพุตและพิมพ์ผลรวมหลังจากการประมวลผลไฟล์ทั้งหมดเสร็จสิ้นแล้วเท่านั้น

AWK ยังมีค่าพิเศษอื่นๆ อีกมากมายที่คุณสามารถใช้ในส่วน ( ) ได้ ตัวอย่างเช่น,

พิมพ์ NF

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

คุณไม่สามารถเปลี่ยนแปลงได้ เอ็นเอฟด้วยตัวเอง

เช่นเดียวกับตัวแปร NRซึ่งจะบอกคุณว่าคุณได้ประมวลผลไปแล้วกี่แถว (“จำนวนบันทึก” - จำนวนบันทึก)

มีตัวแปรพิเศษอื่นๆ แม้กระทั่งตัวแปรที่คุณสามารถเปลี่ยนได้ในระหว่างโปรแกรม

ส่วนที่สี่: ตัวอย่าง Awk แบบง่าย

เพื่ออธิบายและเน้นย้ำสิ่งที่ได้กล่าวไว้ ลองดูบางส่วนกัน ตัวอย่างเฉพาะ- สำหรับพวกเขาเราจะต้องมีไฟล์ข้อความขนาดเล็กสามไฟล์

สำหรับตัวอย่างต่อไปนี้ เรามาสร้างไฟล์ field_data.txt ที่มีเนื้อหาดังต่อไปนี้:

ดอกกุหลาบเป็นสีแดง สีม่วงเป็นสีฟ้า น้ำตาลเป็นรสหวาน และคุณก็เช่นกัน

Echo -e "ดอกกุหลาบเป็นสีแดง\nสีม่วงเป็นสีฟ้า\nน้ำตาลมีรสหวาน\nและคุณก็เช่นกัน" >field_data.txt

มาสร้างไฟล์ letter.txt โดยมีเนื้อหาดังต่อไปนี้

A bb ccc dddd ggg hh ฉัน

ใน บรรทัดคำสั่งสามารถทำได้ดังนี้:

เสียงสะท้อน -e "a\nbb\nccc\ndddd\nggg\nhh\ni" > letter.txt

สุดท้ายนี้ เรามาสร้างไฟล์ข้อมูลเมลที่มีเนื้อหาดังต่อไปนี้:

อมีเลีย 555-5553 [ป้องกันอีเมล]เอฟ แอนโทนี่ 555-3412 [ป้องกันอีเมล]เบ็คกี้ 555-7685 [ป้องกันอีเมล]บิล 555-1675 [ป้องกันอีเมล]บรอเดอริก 555-0542 [ป้องกันอีเมล]อาร์ คามิลล่า 555-2912 [ป้องกันอีเมล]อาร์ ฟาเบียส 555-1234 [ป้องกันอีเมล]เอฟ จูลี่ 555-6699 [ป้องกันอีเมล]เอฟ มาร์ติน 555-6480 [ป้องกันอีเมล]ซามูเอล 555-3430 [ป้องกันอีเมล]ฌอง-ปอล 555-2127 [ป้องกันอีเมล]

ซึ่งสามารถทำได้บนบรรทัดคำสั่งดังนี้:

รับ https://raw.githubusercontent.com/tdhopper/awk-lessons/master/data/mail-data -O เมลข้อมูล

รูปแบบเรียบง่าย (ตัวอย่าง)

หากเราต้องการบรรทัดที่ยาวเกินสองตัวอักขระและเราต้องการใช้การกระทำเริ่มต้น ( พิมพ์) จากนั้นเราจะได้:

Awk "ความยาว $0 > 2" ตัวอักษร.txt bb ccc dddd ggg hh

$0 เป็นตัวแปรบิวท์อินที่มีสตริง

ฟังก์ชั่นที่เรียบง่าย

หากเราไม่ระบุรูปแบบ แต่ละบรรทัดก็จะตรงกัน การดำเนินการเล็กน้อยคือการพิมพ์แต่ละบรรทัด:

Awk "( พิมพ์)" letter.txt a bb ccc dddd ggg hh i

การใช้ฟังก์ชัน ความยาวจากการกระทำของเรา เราจะได้ความยาวของแต่ละบรรทัด:

Awk "( ความยาวการพิมพ์ )" letter.txt 1 2 3 4 3 2 1

การดำเนินการนี้มีผลกับทั้งแถวโดยไม่มีเงื่อนไข นอกจากนี้เรายังสามารถระบุสิ่งนี้ได้อย่างชัดเจน:

Awk "( ความยาวการพิมพ์ $0 )" letter.txt 1a 2bb 3ccc 4dddd 3ggg 2hh 1i

Awk มีการควบคุมพิเศษสำหรับการรันโค้ดบางส่วนก่อนเริ่มอินพุตไฟล์และหลังไฟล์เสร็จสิ้น

Awk "BEGIN ( พิมพ์ "HI" ) ( พิมพ์ $0 ) END ( พิมพ์ "BYE!" )" letter.txt HI a bb ccc dddd ggg hh i BYE!

เราก็มีได้ องค์ประกอบเพิ่มเติมควบคุมระหว่างการพิมพ์โดยใช้ พิมพ์ฉ.

Awk "BEGIN ( printf "%-10s %s\n", "ชื่อ", "หมายเลข" \ printf "%-10s %s\n", "----", "------" ) \ ( printf "%-10s %s\n", $1, $2 )" หมายเลขชื่อข้อมูลเมล ---- ------ Amelia 555-5553 Anthony 555-3412 Becky 555-7685 Bill 555-1675 Broderick 555-0542 Camilla 555-2912 Fabius 555-1234 Julie 555-6699 Martin 555-6480 ซามูเอล 555-3430 Jean-Paul 555-2127

การรวมตัวอย่างและฟังก์ชัน

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

เราสามารถพิมพ์ความยาวของทุกบรรทัดที่ยาวเกิน 2 ตัวอักษรได้

Awk "length($0) > 2 ( ความยาวการพิมพ์($0) )" letter.txt 3 4 3

จริงๆ แล้ว เราไม่จำเป็นต้องจำกัด Awk ไว้เพียงรูปแบบเดียว! เราสามารถมีรูปแบบได้ตามต้องการ โดยคั่นด้วยเครื่องหมายอัฒภาคหรือขึ้นบรรทัดใหม่:

Awk "length($0) > 2 ( พิมพ์ "Long: " length($0) ); length($0)< 2 { print "Short: " length($0) }" letters.txt Short: 1 Long: 3 Long: 4 Long: 3 Short: 1

ทุ่งนามากมาย

Awk ได้รับการออกแบบมาเพื่อการประมวลผลข้อมูลอย่างง่ายโดยมีหลายช่องติดต่อกัน ตัวคั่นฟิลด์สามารถระบุได้ด้วยคีย์ -ฟ.

ตัวอย่างของไฟล์ที่ตัวคั่นเป็นช่องว่าง:

Awk "( print )" field_data.txt ดอกกุหลาบเป็นสีแดง สีม่วงเป็นสีน้ำเงิน น้ำตาลเป็นรสหวาน และคุณก็เช่นกัน

หากเราระบุตัวคั่นฟิลด์ เราสามารถพิมพ์ฟิลด์ที่สองของแต่ละบรรทัดได้:

Awk -F " " "( print $2 )" field_data.txt เป็นเช่นนั้น

เราจะไม่ได้รับข้อผิดพลาดหากแถวไม่มีฟิลด์ที่ตรงกัน เราก็จะเห็นบรรทัดว่าง:

Awk -F " " "( พิมพ์ $4 )" field_data.txt คุณ

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

พิลโครว์, ฮัมฟรีย์, 3 พิลโครว์, โซรา, 1 พลิเนียส, โอลโดน, 4 ราซเนียคกี้, แอนตัน, 7 รัสเซลล์, เบอร์ทรานด์, 0

ตอนนี้เราระบุว่าเป็นตัวคั่น , (ลูกน้ำ) และแสดงเนื้อหาของคอลัมน์ที่สอง:

Awk -F "," "( พิมพ์ $2 )" rates.txt Humphrey Zora Oldone Anton Bertrand

นิพจน์ตัวคั่นจะถูกตีความว่าเป็นนิพจน์ทั่วไป

Awk -F "((so)?are|is) " "(พิมพ์ "ฟิลด์ 1: " $1 "\nฟิลด์ 2: " $2)" field_data.txt ฟิลด์ 1: ดอกกุหลาบ ฟิลด์ 2: สีแดง ฟิลด์ 1: สีม่วง ฟิลด์ 2 : สีฟ้า สนาม 1: น้ำตาล ทุ่ง 2: หวาน สนาม 1: และสนาม 2: คุณ

นิพจน์ทั่วไป

รูปแบบอาจเป็นนิพจน์ทั่วไป ไม่ใช่เพียงฟังก์ชันในตัว

เราสามารถใช้นิพจน์ทั่วไปเพื่อค้นหาคำทั้งหมดในโลก Unix ที่มีสระ 5 ตัวติดต่อกัน

Awk "/(5)/" /usr/share/dict/words cadiueio Chaouia euouae Guauaenok

การส่งผ่านตัวแปรไปยังโปรแกรม

ตัวเลือก -vสำหรับ Awk ให้เราส่งตัวแปรเข้าโปรแกรมได้ ตัวอย่างเช่น เราสามารถใช้สิ่งนี้กับค่าคงที่ฮาร์ดโค้ดได้

Awk -v pi=3.1415 "BEGIN ( พิมพ์ pi )" 3.1415

เรายังสามารถใช้ได้ -vเพื่อส่งตัวแปร Bash เป็นตัวแปร Awk

Awk -v user=$USER "BEGIN (ผู้ใช้การพิมพ์)" mial

นิพจน์ If-else

ถ้า-อย่างอื่นนิพจน์ใน Awk มีลักษณะดังนี้:

ถ้า (เงื่อนไข) ร่างกาย-แล้ว

ตัวอย่างเช่น:

พิมพ์f "1\n2\n3\n4" | awk \ "( \ if ($1 % 2 == 0) พิมพ์ $1, "เป็นคู่"; \ else พิมพ์ $1, "เป็นคี่" \ )" 1 เป็นคี่ 2 เป็นคู่ 3 เป็นคี่ 4 เป็นคู่

รอบ

Awk มีนิพจน์วนซ้ำหลายแบบ: ในขณะที่, ทำในขณะที่และ สำหรับ.

พวกเขามีไวยากรณ์ C ที่คาดหวัง

แย่\"BEGIN(\i=0;\ While(i< 5) { print i; i+=1; } \ }" 0 1 2 3 4 awk \ "BEGIN { \ i = 0; \ do { print i; i+=1; } while(i < 0) \ }" 0 awk \ "BEGIN { \ i = 0; \ for(i = 0; i<5; i++) print i \ }" 0 1 2 3 4

สำหรับยังสามารถกำหนดการวนซ้ำผ่านคีย์อาเรย์ ที่จะมีการหารือในภายหลัง

ส่วนที่ห้า: ฟังก์ชั่นการโทร

องค์ประกอบถัดไปของ AWK คือฟังก์ชันพิเศษในตัวทั้งหมด

AWK มีคุณสมบัติที่จะทำให้โปรแกรมเมอร์ภาษา C โดยเฉลี่ยค่อนข้างพอใจ ที่นี่มีสิ่งต่าง ๆ เช่น sin()/cos()/tan(), rand(),index(), sprintf(), tolower(), system()

ฟังก์ชั่นจะถูกจัดกลุ่มและสามารถดูได้ดังต่อไปนี้:

คณิตศาสตร์

+, -, /, *, sin(), cos(), tan(), atan(), sqrt(), แรนด์(), srand()

พวกเขาพูดเพื่อตัวเอง อย่างน้อยฉันก็อยากจะคิดอย่างนั้น

Awk -v pi=3.1415 "BEGIN ( print exp(1), log(exp(1)), sqrt(2), sin(pi), cos(pi), atan2(pi, 2) )" 2.71828 1 1.41421 9.26536 e-05 -1 1.00387

โปรแกรมสามารถสร้างตัวเลขสุ่มในช่วง (0, 1)

ตามค่าเริ่มต้น Awk จะเริ่มต้นจากจุดเริ่มต้นเดียวกัน (เริ่มต้น) สำหรับ Awk การรันคำสั่งนี้สองครั้งติดต่อกันจะให้ผลลัพธ์เหมือนเดิม:

Awk "BEGIN ( พิมพ์ rand(); พิมพ์ rand() )" 0.237788 0.291066

หากต้องการตั้งค่าเริ่มต้น (seed) คุณสามารถใช้ฟังก์ชัน srand:

Awk "BEGIN ( srand(10); พิมพ์ rand(); พิมพ์ rand() )" 0.255219 0.898883 awk "BEGIN ( srand(10); พิมพ์ rand(); พิมพ์ rand() )" 0.255219 0.898883

การทำงาน ภายในส่งคืน "จำนวนเต็มที่ใกล้เคียงที่สุดกับ x ระหว่าง x ถึงศูนย์ โดยทิ้งศูนย์นำหน้า"

Awk "BEGIN ( พิมพ์ "int(0.9) = " int(0.9); พิมพ์ "int(-0.9) = " int(-0.9) )" int(0.9) = 0 int(-0.9) = 0

การจัดการสตริง

  • ดัชนี()จะบอกคุณว่า และถ้าเป็นเช่นนั้น สตริงเกิดขึ้นภายในสตริงย่อยหรือไม่ และหากเป็นเช่นนั้น
  • จับคู่()คล้ายกัน แต่ใช้ได้กับนิพจน์ทั่วไป
  • วิ่ง()ให้วิธีการจัดรูปแบบเอาต์พุตและทำการแปลงไปพร้อมกัน ใครก็ตามที่เคยใช้ printf() กับ C น่าจะคุ้นเคยกับสิ่งนี้ ตัวอย่างเช่น
newstring=sprintf("หนึ่งคือตัวเลข %d สองคือสตริง %s\n" หนึ่ง สอง); พิมพ์บรรทัดใหม่

"%d" บอกว่า "พิมพ์ค่าที่ตรงกับฉันเป็นเลขทศนิยม"
"%s" บอกว่า "พิมพ์ค่าที่ตรงกับฉันเป็นสตริง"

เหล่านั้น. หากคุณต้องการเชื่อมสองบรรทัดเข้าด้วยกันโดยไม่มีตัวแบ่ง วิธีหนึ่งก็คือการใช้

Newstring=sprintf("%s%s", หนึ่ง, สอง)

  • ความยาว()เพียงให้วิธีง่ายๆ แก่คุณในการนับจำนวนอักขระในบรรทัดหากคุณต้องการ

การทำงาน ส่วนย่อย (s, m, n)จะส่งคืนสตริงย่อยใน n-ตัวละครเริ่มต้นจากตำแหน่ง นับจาก 1

Awk "( print $1, substr($1, 2, 3) )" field_data.txt ดอกกุหลาบ ose Violets iol Sugar uga และ nd

ดัชนี (s, t)ส่งกลับ `ตำแหน่งใน ซึ่งเส้นนั้นเกิดขึ้น ทีหรือ 0 ถ้ามันไม่เกิดขึ้น`

รูปแบบของดัชนีไม่ใช่นิพจน์ทั่วไป

Awk "( พิมพ์ $1, ดัชนี ($1, "s") )" field_data.txt ดอกกุหลาบ 3 สีม่วง 7 น้ำตาล 0 และ 0

การแข่งขัน (s, r)คืนตำแหน่งใน ซึ่งนิพจน์ทั่วไปเกิดขึ้น หรือ 0 หากไม่เกิดขึ้น ตัวแปร เริ่มต้นใหม่และ ความยาวถูกตั้งค่าเป็นตำแหน่งและความยาวของสตริงที่ตรงกัน

จับคู่- เป็นยังไงบ้าง ดัชนียกเว้นว่ารูปแบบนั้นเป็นนิพจน์ทั่วไป

Awk "( print $1, match($1, "") )" field_data.txt ดอกกุหลาบ 3 สีม่วง 7 น้ำตาล 1 และ 0 # "ค้นหาตัวอักษรที่ซ้ำกันสามตัวขึ้นไป" awk "( match($1, "(3)"); พิมพ์ $1, "\tรูปแบบเริ่มต้น:", RSTART, "\tรูปแบบสิ้นสุด:", RLENGTH )" letter.txt เริ่มต้นรูปแบบ: 0 สิ้นสุดรูปแบบ: -1 bb เริ่มต้นรูปแบบ: 0 สิ้นสุดรูปแบบ: -1 ccc เริ่มต้นรูปแบบ: 1 รูปแบบ สิ้นสุด: 3 dddd เริ่มต้นรูปแบบ: 1 สิ้นสุดรูปแบบ: 3 ggg เริ่มต้นรูปแบบ: 1 สิ้นสุดรูปแบบ: 3 hh เริ่มต้นรูปแบบ: 0 สิ้นสุดรูปแบบ: -1 i เริ่มต้นรูปแบบ: 0 สิ้นสุดรูปแบบ: -1

แยก (s, a, fs)แยกสตริงออกเป็นอาร์เรย์ขององค์ประกอบ a, a, …, a และส่งคืน n.

การหารทำได้โดยนิพจน์ทั่วไป FSหรือมีเครื่องแยกสนาม เอฟเอส, ถ้า FSไม่ให้. สตริงว่างเป็นตัวคั่นฟิลด์แยกสตริงออกเป็นอาร์เรย์ขององค์ประกอบอักขระตามอักขระ

Awk "BEGIN ( print split("It-was_the-best_of-times", output_array, "[-_]"), output_array, output_array )" 6 ดีที่สุด

ย่อย (r, t, s)แทนที่ด้วย ทีการเกิดขึ้นครั้งแรกของนิพจน์ทั่วไป ในบรรทัด - หากไม่ได้รับ s ให้ใช้ $0

คือสตริงที่มีการแทนที่เกิดขึ้น แทนที่จะส่งคืนสตริงใหม่พร้อมกับการแทนที่ ระบบจะส่งคืนจำนวนการแทนที่ (0 หรือ 1)

Awk "BEGIN ( s = "มันเป็นช่วงเวลาที่ดีที่สุด มันเป็นช่วงเวลาที่แย่ที่สุด"; \ print "Num.matches ถูกแทนที่:", sub("times", "gifs", s); \ print s )" หมายเลข การแข่งขันถูกแทนที่: 1 มันเป็น GIF ที่ดีที่สุด มันเป็นช่วงเวลาที่แย่ที่สุด

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

Awk "BEGIN ( s = "มันเป็นช่วงเวลาที่ดีที่สุด มันเป็นช่วงเวลาที่แย่ที่สุด"; \ print "Num.matches ถูกแทนที่:", gsub("times", "cats", s); \ print s )" หมายเลข การแข่งขันที่ถูกแทนที่: 2 มันเป็นแมวที่ดีที่สุด มันเป็นแมวที่แย่ที่สุด sprintf sprintf(fmt, expr, ...) ส่งคืนสตริงที่เกิดจากการจัดรูปแบบ expr ... ตามรูปแบบ printf(3) fmt awk "BEGIN ( x = sprintf("[%8.3f]", 3.141592654); พิมพ์ x )" [ 3.142]

ฟังก์ชั่นระดับระบบ

ระบบ()ช่วยให้คุณสามารถเรียกไฟล์ปฏิบัติการใด ๆ ที่อาจเป็นไปได้บนระบบ โปรแกรมเป้าหมายอาจอยู่ในของคุณ $พาธหรือคุณสามารถระบุโดยใช้เส้นทางที่แน่นอน

เช่น น่ากลัว

ระบบ("rm -rf $HOME");

ระบบ ("/bin/kill 1")

หากคุณต้องการทำสิ่งที่ซับซ้อนกว่านี้ คุณก็อาจจะลงเอยด้วยการทำสิ่งที่คล้ายกัน

Sysstring=sprintf("คำสั่งบางอย่าง %s %s", arg1, arg2); ระบบ(sysstring)

ปิด()เป็นคุณสมบัติสำคัญที่มักถูกมองข้าม อาจเป็นเพราะไม่มีการโทรที่ชัดเจน เปิด()คนจึงไม่คิดถึงความท้าทาย ปิด()- และสำหรับวัตถุประสงค์ส่วนใหญ่ สิ่งนี้ไม่จำเป็น แต่คุณต้องทำสิ่งนี้หากคุณกำลังจัดการกับไฟล์เอาต์พุตมากกว่าหนึ่งไฟล์

Awk ช่วยให้คุณสามารถเปิดไฟล์ที่ต้องการได้ทันที ตัวอย่างเช่น

/^ไฟล์/ ( พิมพ์ $3 >> $2 )

ควรใช้บรรทัด "file output here-is-a-word" เปิดไฟล์ "output" และพิมพ์ "here-is-a-word" ลงไป

AWK นั้น "ฉลาด" ในเรื่องที่จะติดตามไฟล์ที่คุณเปิดและเปิดไฟล์เหล่านั้นไว้ โดยถือว่าถ้าคุณเปิดไฟล์ครั้งหนึ่ง คุณอาจจะเปิดไฟล์อีกครั้ง น่าเสียดาย ซึ่งหมายความว่าหากคุณเปิดไฟล์จำนวนมาก คุณอาจไม่มีตัวอธิบายไฟล์ ดังนั้นเมื่อคุณรู้ว่าคุณใช้ไฟล์เสร็จแล้ว ให้ปิดมัน ดังนั้นเพื่อปรับปรุงตัวอย่างข้างต้น คุณควรใช้บรรทัดต่อไปนี้:

/^file/ ( if ($2 != oldfile) ( close(oldfile) ); พิมพ์ $3 >> $2 ; oldfile = $2; )

ส่วนที่หก: อาร์เรย์

แนวคิดเรื่องอาร์เรย์

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

หากคุณต้องการมีค่าสามค่า คุณสามารถพูดได้ว่า:

Value1="หนึ่ง"; value2="สอง"; value3="สาม";

หรือคุณสามารถใช้

ค่า = "หนึ่ง"; ค่า = "สอง"; ค่า = "สาม";

ตัวอย่างแรกคือตัวแปรสามตัวที่มีชื่อเป็นของตัวเอง (ซึ่งแตกต่างกันด้วยอักขระหนึ่งตัว) ตัวอย่างที่สองคืออาร์เรย์ที่ประกอบด้วยตัวแปรหนึ่งตัว แต่มีหลายค่า ซึ่งแต่ละค่าจะมีหมายเลขของตัวเอง

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

ค่า = "หนึ่ง"; ค่า = "ค่าใหม่";

อย่างไรก็ตาม คุณสามารถกำหนดค่าใหม่ได้เหมือนกับที่คุณทำกับตัวแปรปกติ เหล่านั้น. ต่อไปนี้ถูกต้อง:

ค่า = "1"; พิมพ์ค่า; ค่า = "หนึ่ง"; พิมพ์ค่า;

สิ่งที่น่าสนใจคือ ไม่เหมือนกับภาษาอื่นๆ ตรงที่คุณไม่ได้ถูกบังคับให้ใช้แต่ตัวเลขเท่านั้น ในตัวอย่างข้างต้น ,, จริงๆ แล้วถูกตีความว่าเป็น [“1”], [“2”], [“3”] ซึ่งหมายความว่าคุณสามารถใช้สตริงอื่นๆ เป็นตัวระบุได้ และถือว่าอาร์เรย์เกือบจะเหมือนกับฐานข้อมูลคอลัมน์เดียว ชื่ออย่างเป็นทางการของสิ่งนี้คือ "อาร์เรย์ที่เกี่ยวข้อง"

ตัวเลข["หนึ่ง"]=1; ตัวเลข["สอง"]=2; พิมพ์หมายเลข["หนึ่ง"]; ค่า="two"; print numbers; value=$1; if(numbers = ""){ print "no such number"; } !}

เมื่อใดและอย่างไรจึงจะใช้อาร์เรย์

อาจมีหลายกรณีที่คุณอาจเลือกใช้อาร์เรย์ เมื่อทำงานกับ awk บางคนจะทำโดยไม่มีอาร์เรย์เลย แต่นี่ไม่ใช่ตำแหน่งที่ถูกต้องทั้งหมด: สำหรับอาร์เรย์มีตัวแปรพิเศษที่แสดงขนาด (จำนวนค่าในอาร์เรย์) มีโครงสร้างที่สะดวกสำหรับการแจกแจงสมาชิกอาร์เรย์และบางฟังก์ชันส่งคืนค่า ในรูปแบบของอาร์เรย์ อย่างไรก็ตาม เรามาดูตัวอย่างที่อาจมีประโยชน์กันดีกว่า

การบันทึกข้อมูลเพื่อใช้ในภายหลัง

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

/พิเศษ/( savewords=$2; lnum+=1; ) END ( count=0; while(savedwords != "") ( print count,savedwords; count+=1; ) )

แทนที่จะแสดงคำเพียงอย่างเดียว คุณสามารถใช้ส่วน END เพื่อดำเนินการเพิ่มเติมใดๆ ที่คุณอาจต้องการก่อนที่จะแสดงคำเหล่านั้น

หากคุณต้องการกำหนดดัชนีเฉพาะให้กับค่า (เพื่อหลีกเลี่ยงการซ้ำกัน) คุณสามารถอ้างอิงถึงค่าเหล่านั้นตามแถวของตัวเองได้ หรือ ตัวอย่างเช่น บันทึกอาร์เรย์ด้วยคอลัมน์ 3 ซึ่งจัดทำดัชนีโดยค่าที่สอดคล้องกันในคอลัมน์ 2

( threecol[$2]=$3 ) END ( สำหรับ (v ใน threecol) ( พิมพ์ v, threecol[v] ) )

อาร์เรย์และการแยก ()

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

นี่คือบรรทัดตัวแปร:field:type สามารถมีได้หลาย:type:values ​​​​ที่นี่

ในตัวอย่างข้างต้น ฟิลด์ที่สี่ซึ่งคั่นด้วยช่องว่าง มีฟิลด์ย่อยที่คั่นด้วยเครื่องหมายทวิภาค ตอนนี้ สมมติว่าคุณต้องการทราบค่าของฟิลด์ย่อยที่สองในฟิลด์ใหญ่ที่สี่ วิธีหนึ่งในการทำเช่นนี้คือการเรียก awks สองตัวที่เชื่อมต่อกันด้วยไปป์:

Awk "(พิมพ์ $4)" | awk -F: "(พิมพ์ $2)"

อีกวิธีหนึ่งคือการเปลี่ยนค่าของ "FS" ทันทีซึ่งมีตัวคั่นฟิลด์ (เห็นได้ชัดว่านี่ใช้ไม่ได้กับการใช้งาน awk ทั้งหมด):

Awk "( newline=$4; fs=FS; FS= Marriott; $0=newline; print $2 ; FS=fs; )"

แต่คุณสามารถทำได้กับอาร์เรย์โดยใช้ฟังก์ชัน split() ดังนี้:

Awk "( newline=$4; split(newline,subfields,"); print subfields) "

ในกรณีนี้ การใช้อาร์เรย์เป็นวิธีที่ธรรมดาที่สุดและอาจเป็นวิธีที่หรูหราที่สุด

ดังนั้น Awk จึงมีโครงสร้างข้อมูลจำนวนจำกัด นอกจากตัวแปรสเกลาร์และสตริงแล้ว ภาษายังมีโครงสร้างข้อมูลขนาดใหญ่ในตัวอีกด้วย แม้ว่าจะเรียกอย่างเป็นทางการว่า "อาร์เรย์" แต่จริงๆ แล้วโครงสร้างนี้เป็นอาร์เรย์ที่เกี่ยวข้องกัน คล้ายกับโครงสร้างข้อมูล dict ใน Python

ไม่จำเป็นต้องเริ่มต้นอาร์เรย์ คุณก็สามารถเริ่มกำหนดค่าได้ โปรดทราบว่าคีย์อาจเป็นตัวเลขหรือสตริงก็ได้

Awk "BEGIN ( \ a = 1.1; \ a = 0; \ a["DOG"] = "CAT"; \ print a, a, a["DOG"] \ )" 1.1 0 CAT

Awk จะไม่พิมพ์ตัวแปรโดยไม่มีดัชนี:

Awk "BEGIN ( \a["DOG"] = "CAT"; \print a\ )" awk: cmd. บรรทัด: 3: ร้ายแรง: พยายามใช้อาร์เรย์ `a" ในบริบทแบบสเกลาร์

แม้ว่าเราจะสามารถวนซ้ำโดยใช้คีย์ได้ สำหรับ:

Awk "BEGIN ( \ a = 1.1; \ a = 0; \ a["DOG"] = "CAT"; \ for(k in a) print(a[k]) \ )" CAT 0 1.1

ส่วนที่เจ็ด: AWK และเชลล์ (sh/ksh/bash/csh)

บางครั้งฟังก์ชันการทำงานของ AWK อาจไม่เพียงพอ ในกรณีนี้ คุณสามารถรวม awk เข้ากับเชลล์สคริปต์ของคุณได้ ด้านล่างนี้เป็นตัวอย่างของวิธีการดังกล่าว

สรุปง่ายๆ

บางครั้งคุณต้องการใช้ awk เช่นเดียวกับฟอร์แมตเตอร์ และดัมพ์เอาต์พุตไปยังผู้ใช้โดยตรง สคริปต์ต่อไปนี้ใช้ชื่อผู้ใช้เป็นอาร์กิวเมนต์ และใช้ awk เพื่อดัมพ์ข้อมูลของผู้ใช้จาก /etc/passwd

บันทึก: โปรดทราบว่าในสคริปต์ เครื่องหมายคำพูดเดี่ยวจะถูกขยาย (ไม่ซ้อนกัน) และระหว่างคู่ที่ขยายสองคู่ของเครื่องหมายคำพูดเดี่ยวจะมีตัวแปร $1 (ตัวที่สอง) ซึ่งในกรณีนี้คืออาร์กิวเมนต์ของสคริปต์ ในขณะที่ $1 เป็นส่วนหนึ่งของไวยากรณ์ $1 (หมายถึงฟิลด์แรกในบรรทัด)

#!/bin/sh ขณะที่ [ "$1" != "" ] ; ทำ awk -F: "$1 == ""$1"" ( พิมพ์ $1,$3) " /etc/passwd เปลี่ยนเสร็จแล้ว

การกำหนดตัวแปรเชลล์เอาต์พุต awk

บางครั้งเราต้องการใช้ awk เพื่อตั้งค่าตัวแปรอย่างรวดเร็ว เมื่อใช้ธีม passwd เราจะมีวิธีค้นหาเชลล์สำหรับผู้ใช้และดูว่าอยู่ในรายการเชลล์อย่างเป็นทางการหรือไม่

โปรดสังเกตว่าเครื่องหมายคำพูดเดี่ยวถูกปิดในนิพจน์ awk อย่างไร หลังจากเครื่องหมายคำพูดปิด (ที่สอง) $1 จะเป็นตัวแปรที่ส่งผ่านค่าของอาร์กิวเมนต์แรกไปยังสคริปต์ ไม่ใช่ส่วนหนึ่งของไวยากรณ์ awk

#!/bin/sh user="$1" ถ้า [ "$user" == "" ] ; จากนั้นก้องข้อผิดพลาด: ต้องการชื่อผู้ใช้ ; ออก ; fi usershell=`awk -F: "$1 == ""$1"" ( พิมพ์ $7) " /etc/passwd` grep -l $usershell /etc/shells ถ้า [ $? -ne 0 ] ; จากนั้นก้องข้อผิดพลาด: เชลล์ $usershell สำหรับผู้ใช้ $user ไม่ได้อยู่ใน /etc/shells fi

ทางเลือกอื่น:

# ดู "man regex" usershell=`awk -F: "/^"$1":/ ( พิมพ์ $7) " /etc/passwd` echo $usershell; # เฉพาะ awk สมัยใหม่เท่านั้นที่ยอมรับ -v คุณอาจจำเป็นต้องใช้ "nawk" หรือ "gawk" usershell2=`awk -F: -v user=$1 "$1 == user ( print $7) " /etc/passwd` echo $usershell2;

การอธิบายวิธีการเพิ่มเติมข้างต้นถือเป็นการบ้านสำหรับผู้อ่าน :)

การถ่ายโอนข้อมูลไปยัง awk ผ่านทางไพพ์

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

#!/bin/sh grep -h " /index.html" $* | awk -F\" "(พิมพ์ $4)" | sort -u

  1. บทความที่น่าสนใจ ฉันอยากจะขอบคุณสำหรับความพยายามของคุณ

    ฉันพบว่ามันไม่ถูกต้อง หากคุณดำเนินการบรรทัดจากตัวอย่าง

    Awk -F " " "( พิมพ์ $2 )" field_data.txt

    มันจะส่งออกสิ่งเดียวกันกับ

    Awk "( พิมพ์ $2)" field_data.txt

    ผลลัพธ์ที่ได้คือตัวอย่างที่มี -ฟอธิบายไม่ถูก

AWK(1)

ชื่อ
awk - การจับคู่รูปแบบและการแปลงข้อความ

ไวยากรณ์

Awk [-Fสัญลักษณ์] [[-f] โปรแกรม] [อาร์กิวเมนต์...] [ไฟล์...]

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

คำสั่ง awk สามารถส่งผ่านอาร์กิวเมนต์ในรูปแบบ x=... y=... เป็นต้น (ดูตัวอย่าง)

ไฟล์จะถูกอ่านตามลำดับที่ได้รับ หากไม่มีการระบุไฟล์หรือชื่อเป็น - ระบบจะใช้อินพุตมาตรฐาน อินพุตสำหรับ awk ถูกแบ่งออกเป็นรายการที่คั่นด้วยอักขระพิเศษ ค่าเริ่มต้นคือการป้อนบรรทัด ในกรณีนี้ awk จะประมวลผลอินพุตทีละบรรทัด ตัวคั่นระเบียนสามารถเปลี่ยนแปลงได้โดยการแทนที่ตัวแปร RS แต่ละเรกคอร์ดจะถูกแบ่งออกเป็นฟิลด์ที่คั่นด้วยตัวคั่นฟิลด์ (ช่องว่างตามค่าเริ่มต้น) ตัวคั่นนี้สามารถเปลี่ยนแปลงได้โดยการกำหนดตัวแปร FS ใหม่ หรือโดยการระบุแฟล็ก -FCharacter ฟิลด์แถวต้นทางมีอยู่ในชื่อ $1, $2,...; $0 คือสตริงอินพุตทั้งหมด

สำหรับแต่ละเทมเพลตจากโปรแกรม คุณสามารถระบุการดำเนินการที่จะดำเนินการกับสตริงใดๆ ที่ตรงกับเทมเพลตได้สำเร็จ ตัวดำเนินการ template-action มีรูปแบบ:

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

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

ถ้า (เงื่อนไข) คำสั่ง [ คำสั่ง else ] ในขณะที่ (เงื่อนไข) คำสั่งสำหรับ (นิพจน์; เงื่อนไข; นิพจน์) แบ่งคำสั่งต่อไป ( [ คำสั่ง ] ... ) ตัวแปร = นิพจน์ พิมพ์ [ expression_list ] [> นิพจน์ ] รูปแบบ printf [, expression_list ] [> expression ] next # ข้ามรูปแบบที่เหลือ และไปที่บรรทัดถัดไป exit # ข้ามบรรทัดที่เหลือ

คำสั่งจะสิ้นสุดลงด้วยเครื่องหมายอัฒภาค ขึ้นบรรทัดใหม่ หรือวงเล็บขวา expression_list ว่างหมายถึงสตริงทั้งหมด นิพจน์ถูกสร้างขึ้นจากสตริงอักขระและตัวเลขโดยใช้การดำเนินการ +, -, *, /, % และการต่อข้อมูล (ระบุด้วยช่องว่าง) คุณยังสามารถใช้โอเปอเรเตอร์จากภาษา C ในนิพจน์: ++, --, +=, -=, *=, /=, %= ตัวแปรจะเริ่มต้นด้วยสตริงว่าง ตัวแปรอาจเป็นสเกลาร์ องค์ประกอบอาร์เรย์ (แสดงด้วย x[i]) หรือฟิลด์ ดัชนีอาร์เรย์อาจเป็นสตริงอักขระใดๆ (ไม่จำเป็นต้องเป็นตัวเลข) ซึ่งทำให้สามารถใช้หน่วยความจำแบบเชื่อมโยงได้ สตริงอักขระจะอยู่ในเครื่องหมายคำพูดคู่ (")

คำสั่ง print จะพิมพ์อาร์กิวเมนต์ไปยังเอาต์พุตมาตรฐาน (หรือไปยังไฟล์หากมีส่วน >expression) โดยแยกอาร์กิวเมนต์เหล่านั้นด้วยตัวคั่นฟิลด์ปัจจุบัน และสิ้นสุดแต่ละเร็กคอร์ดด้วยตัวคั่นเร็กคอร์ดเอาต์พุต คำสั่ง printf ทำสิ่งเดียวกัน แต่อยู่ภายใต้การควบคุมรูปแบบ [ดู พิมพ์f(3S) ].

ฟังก์ชันบิวท์อินความยาวจะส่งกลับความยาวของอาร์กิวเมนต์ โดยถือว่ามันเป็นสตริงของอักขระ ถ้าละเว้นอาร์กิวเมนต์ ความยาวของบรรทัดปัจจุบันจะถูกส่งกลับ นอกจากนี้ยังมีการกำหนดฟังก์ชันในตัวต่อไปนี้: exp, log, sqrt และ int (int ละทิ้ง เศษส่วนข้อโต้แย้งของคุณ) ฟังก์ชั่น substr(s, m, n) ส่งคืนสตริงย่อย n ตัวอักษรของ s เริ่มต้นที่ตำแหน่ง m ฟังก์ชัน sprintf(format, expression, expression,...) แปลงนิพจน์ตามรูปแบบที่ระบุ [ดู printf(3S) ] และส่งคืนสตริงอักขระผลลัพธ์

เทมเพลตเป็นไปตามอำเภอใจ การรวมกันเชิงตรรกะประกอบด้วยตัวดำเนินการ !, ||, && และวงเล็บจากนิพจน์ทั่วไปและนิพจน์การเปรียบเทียบ นิพจน์ทั่วไปล้อมรอบด้วย / [ดู egrep(1) สำหรับรายละเอียด] นิพจน์ทั่วไปเดียวในรูปแบบจะถูกจับคู่กับสตริงทั้งหมด นิพจน์ทั่วไปสามารถรวมอยู่ในนิพจน์การเปรียบเทียบได้เช่นกัน รูปแบบอาจประกอบด้วยสองรูปแบบโดยคั่นด้วยเครื่องหมายจุลภาค ในกรณีนี้ การดำเนินการที่ระบุจะถูกดำเนินการกับทุกบรรทัดระหว่างเส้นที่ตรงกับรูปแบบแรกและเส้นที่ตรงกับรูปแบบที่สอง

นิพจน์การเปรียบเทียบเป็นหนึ่งในโครงสร้างต่อไปนี้:

นิพจน์ oper_compare นิพจน์ปกติ นิพจน์ oper_compare

โดยที่ oper_compare คือตัวดำเนินการเปรียบเทียบ C หกตัว oper_compare คือ ~ (มี) หรือ !~ (ไม่มี)

สภาพคือ นิพจน์ทางคณิตศาสตร์นิพจน์เปรียบเทียบ หรือการรวมกันเชิงตรรกะของนิพจน์ดังกล่าว

ดำเนินการใดๆ ก่อนหรือหลังประการแรก บรรทัดสุดท้ายมีการกำหนดรูปแบบพิเศษ BEGIN และ END BEGIN ต้องเป็นรูปแบบแรก END ต้องเป็นรูปแบบสุดท้าย ตัวอย่างเช่น หากต้องการใช้อักขระ c เป็นตัวคั่นฟิลด์ คุณสามารถรันโปรแกรมด้วยอ็อพชัน -Fc หรือระบุ

BEGIN ( FS = c ) ตัวแปรพิเศษอื่นๆ: NF จำนวนฟิลด์ในบันทึกปัจจุบัน NR หมายเลขซีเรียลรายการปัจจุบัน FILENAME ชื่อของไฟล์ที่มาจาก ช่วงเวลานี้ป้อนข้อมูลแล้ว OFS ตัวคั่นฟิลด์สำหรับเอาต์พุต ช่องว่างตามค่าเริ่มต้น ORS ตัวคั่นบันทึกสำหรับเอาต์พุต ป้อนบรรทัดตามค่าเริ่มต้น รูปแบบเอาต์พุตตัวเลข OFMT ค่าเริ่มต้น %.6g

ตัวอย่าง

  1. พิมพ์บรรทัดในไฟล์ f1 ที่มีอักขระมากกว่า 72 ตัว: awk "length > 72" f1
  2. พิมพ์สองฟิลด์แรกของไฟล์ f2 ในลำดับย้อนกลับ: awk "( print $2, $1 )" f2
  3. เพิ่มตัวเลขในคอลัมน์แรกของไฟล์ f3 พิมพ์ผลรวมและค่าเฉลี่ยเลขคณิต:
    ในไฟล์ prog: ( s += $1 ) END ( พิมพ์ "sum is", s, " Average is", s/NR ) บรรทัดคำสั่ง: awk -f prog f3
  4. พิมพ์ฟิลด์ของไฟล์ f4 ในลำดับย้อนกลับ: awk "( for (i = NF; i > 0; --i) print $i )" f4
  5. พิมพ์ไฟล์ f5 ทุกบรรทัดระหว่างคู่ start/stop awk "/start/,/stop/" f5
  6. พิมพ์บรรทัดของไฟล์ f6 ซึ่งฟิลด์แรกไม่ตรงกับฟิลด์แรกของบรรทัดก่อนหน้า: awk "$1 != prev ( print; prev = $1 )" f6
  7. พิมพ์ไฟล์ f7 โดยใส่จำนวนหน้าหลังคำว่า "หน้า" โดยเริ่มจากหน้าที่ห้า:
    ในไฟล์ prog: /Page/ ( $2 = n++ ) ( print ) บรรทัดคำสั่ง: awk -f prog n=5 f7

ซม. อีกด้วย
egrep(1) , ไฟแนนซ์(1) , sed(1) .
printf(3S) ในข้อมูลอ้างอิงของโปรแกรมเมอร์

เซอร์ไพรส์
ช่องว่างอินพุตจะไม่ถูกรักษาไว้ในเอาต์พุตหากมีการแก้ไขฟิลด์ของเรกคอร์ดนั้น

ภาษาคำสั่ง awk ไม่มีการแปลงที่ชัดเจนระหว่างสตริงอักขระและตัวเลข หากต้องการถือว่านิพจน์เป็นตัวเลข ให้เพิ่ม 0 เข้าไป ให้ถือเป็นลูกโซ่เชื่อมเข้ากับโซ่ว่าง ""