อะไรคือความแตกต่างที่แน่นอนระหว่าง awk และตัดด้วย grep? [ปิด]


30

เรารู้ว่าเราสามารถรับคอลัมน์ที่สองของบรรทัดที่เราต้องการจากไฟล์โดยใช้เทคนิคทั้งสองนี้:

awk '/WORD/ { print $2 }' filename

หรือ

grep WORD filename| cut -f 2 -d ' '

คำถามของฉันคือ:

  • อะไรคือความแตกต่างระหว่างสองคำสั่งด้านบน?
  • อันไหนมีประสิทธิภาพดีที่สุด?
  • อะไรคือข้อดีของการใช้awkเกินกว่าcutและในทางกลับกัน?
  • ตัวเลือกอะไรที่awkทำให้เรามีcutทางกลับกัน?

คือว่าecho filenameหรือcat filename?
Avinash Raj

@AvinashRaj ขอโทษแก้ไข
Networker

คำตอบ:


35

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

กรุณาเปรียบเทียบ:

$ echo "abc def" | cut -f 2 -d ' '
def
$ echo "abc    def" | cut -f 2 -d ' '

$ echo " abc def" | cut -f 2 -d ' '
abc


$ echo "abc def" | awk '{ print $2 }'
def
$ echo "abc    def" | awk '{ print $2 }'
def
$ echo " abc def" | awk '{ print $2 }'
def

ที่นี่awkแยกตามลำดับของช่องว่างระหว่างabcและdefในขณะที่cutใช้ทุกช่องว่างเป็นตัวคั่น

สิ่งที่คุณทำจะขึ้นอยู่กับสิ่งที่คุณต้องการบรรลุ มิฉะนั้นฉันคาดว่าcutจะเร็วขึ้นเพราะมันเป็นเครื่องมืออเนกประสงค์ขนาดเล็กในขณะที่awkมีภาษาการเขียนโปรแกรมของตัวเอง


สิ่งที่ฉันต้องการเป็นคำตอบขอบคุณฉันจะทำเครื่องหมายคำถามเป็นคำตอบ @Dubu
Networker

1
cutมีแนวโน้มว่าจะเร็วกว่า Awk เพียงอย่างเดียวแต่ก็ไม่แน่ว่าgrep ... | cutจะเร็วกว่า Awk ที่บริสุทธิ์
Wildcard

8

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

ข้อดีของเครื่องมือที่ซับซ้อนกว่าคือแน่นอนว่าพวกเขาสามารถทำสิ่งต่าง ๆ ได้มากขึ้น

คำสั่งของคุณใช้แมวโดยไม่จำเป็น ใช้การเปลี่ยนเส้นทางแทน (โดยเฉพาะอย่างยิ่งถ้าคุณกังวลเรื่องความเร็วแม้ว่าคุณอาจไม่ควรกังวลเกี่ยวกับความเร็วจนกว่าคุณจะรันการวัดประสิทธิภาพ¹)

<fileName awk '/WORD/ { print $2 }'
<fileName grep WORD | cut -f 2 -d ' '

คำสั่งเหล่านี้เกือบเทียบเท่า ความแตกต่างคือ:

  • awk และ grep มีไวยากรณ์ regexp ที่แตกต่างกัน Awk และgrep -Eมีซินแท็กซ์ regexp เกือบเหมือนกัน (นิพจน์ทั่วไปที่ขยายเพิ่ม)
  • cut -d ' 'ปฏิบัติต่ออักขระช่องว่างแต่ละรายการเป็นตัวคั่น ตัวคั่นเริ่มต้นของ Awk คือลำดับช่องว่างใด ๆ ซึ่งอาจเป็นช่องว่างหลาย ๆ แท็บ ฯลฯ คุณไม่สามารถใช้ลำดับช่องว่างตามอำเภอใจเป็นตัวคั่นcutได้ การใช้ช่องว่างของแต่ละบุคคลเป็นตัวคั่นใน awk ตั้งคั่นฟิลด์ regexp ที่ตรงกับพื้นที่เดียว, อื่น ๆ กว่า regexp ประกอบด้วยพื้นที่เดียว (ซึ่งเป็นกรณีพิเศษหมายถึง“ลำดับช่องว่างใด ๆ” คือเริ่มต้น) awk -F '[ ]' '/WORD/ {print $2}'A:

¹ กฎข้อแรกของการเพิ่มประสิทธิภาพโปรแกรม: อย่าทำ กฎข้อที่สองของการเพิ่มประสิทธิภาพโปรแกรม (สำหรับผู้เชี่ยวชาญเท่านั้น!): อย่าทำเลย - Michael A. Jackson


1

คำสั่งของคุณ

cat fileName | awk '/WORD/ { print $2 }'

คุณไม่จำเป็นต้องมีแม้แต่catคำสั่ง คุณอาจลอง

awk '/WORD/ { print $2 }' filename

และคำสั่งด้านล่างเปลี่ยนเส้นทางเอาต์พุตจาก cat ไปยัง grep จากนั้นตัด

cat fileName | grep WORD | cut -f 2 -d ' '

ส่วนใหญ่เราจะต้องหลีกเลี่ยงการเปลี่ยนเส้นทางออก Awk ทำงานในบรรทัดเดียว แต่cutต้องการgrepคำสั่งเพื่อรับเฉพาะบรรทัดที่มีคำเฉพาะและพิมพ์คอลัมน์ 2 ตามพื้นที่ตัวคั่น

คุณสามารถทำสิ่งต่าง ๆ ใน awk ถ้าตัดล้มเหลวในการทำ


3
ps คุณไม่ต้องการคำสั่ง cat สำหรับ grep เช่นกัน grep WORD filenameคุณก็สามารถทำ
phoops

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