เริ่มต้นและสิ้นสุดด้วยคำสั่ง awk


13

ตามคู่มือ awk, BEGIN และ END ไม่ได้ใช้เพื่อจับคู่อินพุต แต่ให้ข้อมูลการเริ่มต้นและล้างข้อมูลให้กับสคริปต์ awk นี่คือตัวอย่างที่ได้รับ:

ls -l | \
awk 'BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }'
Files found:
amd.conf
antivir.conf
xcdroast.conf
xinetd.conf

ก่อนอื่นนี้พิมพ์สตริงเพื่อส่งออก จากนั้นจะตรวจสอบอินพุตสำหรับการจับคู่รูปแบบโดยที่อินพุตเริ่มต้นด้วย a หรือ x ตามด้วยอักขระใด ๆ หนึ่งหรือหลายครั้งตามด้วย. conf สำหรับการแข่งขันใด ๆ คอลัมน์ที่ 9 จะถูกพิมพ์

ความจริงที่ว่าเราถูกบังคับให้ใช้เริ่มต้นที่นี่นั่นหมายความว่า awk สามารถใช้ได้กับฟังก์ชั่นการพิมพ์ส่วนใหญ่ที่มี BEGIN หรือ END เท่านั้น? ถ้าไม่เช่นนั้นทำไมเราไม่สามารถใช้ฟังก์ชั่นการพิมพ์ที่จุดเริ่มต้นโดยไม่มีคำหลัก BEGIN ดูเหมือนว่า BEGIN จะฟุ่มเฟือย


เพียงแค่เรียกใช้คำสั่งโดยไม่ต้อง BEGIN จะตอบคำถามของคุณแสดงว่ามันไม่ฟุ่มเฟือยและคุณจะได้รับผลลัพธ์ที่แตกต่าง
msb

คำตอบ:


11

BEGINไม่ฟุ่มเฟือย ถ้าคุณไม่ได้ระบุBEGINแล้วprintจะได้รับการดำเนินการสำหรับสายของทุกท่าน

ข้อความจากคู่มือ :

BEGINกฎจะถูกดำเนินการเพียงครั้งเดียวก่อนที่จะบันทึกการป้อนข้อมูลครั้งแรกที่อ่าน ในทำนองเดียวกันเป็นENDกฎจะถูกดำเนินการเพียงครั้งเดียวหลังจากทั้งหมดเข้าเป็นอ่าน

$ seq 5 | awk 'BEGIN{print "Hello"}/4/{print}'   # Hello printed once
Hello
4
$ seq 5 | awk '{print "Hello"}/4/{print}'        # Hello printed for each line of input
Hello
Hello
Hello
Hello
4
Hello
$

7

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


2

awkรันทุก ๆ บล็อกเฉพาะเมื่อรูปแบบก่อนที่จะตรงกัน รูปแบบที่ว่างเปล่า (บล็อกเพียง) ตรงกับทุกบรรทัด BEGINและENDเป็นรูปแบบพิเศษที่ตรงกับจุดเริ่มต้นและจุดสิ้นสุดของไฟล์ (คล้ายกับความหมายของ^และ$ในแนวนอน)

BEGINถ้าคุณต้องการสิ่งที่จะดำเนินการก่อนที่จะอ่านไฟล์ใช้งาน ตัวอย่างเช่นการเริ่มต้นของเคาน์เตอร์หรือบางสิ่งบางอย่าง ENDสามารถรวบรวมผลลัพธ์ได้


0

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

1 == NR            { print "Files found:\n" }
/\<[a|x].*\.conf$/ { print $9               }

จะให้ผลลัพธ์ที่เหมือนกันเนื่องจากคำสั่งพิมพ์ถูก จำกัด ให้อยู่ที่บรรทัดแรกของอินพุตเท่านั้น

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

BEGIN { print sqrt(12/4) }

คุณสามารถดูตัวอย่างที่รุนแรงมากขึ้นของการเขียนโปรแกรมในการประมวลผล Awk โดยไม่ต้องป้อนข้อมูลใด ๆ ที่นี่

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.