เหตุผลว่าทำไม
tac file | grep foo | head -n 1
ไม่หยุดที่คู่แรกเป็นเพราะการบัฟเฟอร์
โดยปกติแล้วhead -n 1จะออกหลังจากอ่านบรรทัด ดังนั้นgrepควรรับ SIGPIPE และออกเช่นกันทันทีที่มันเขียนบรรทัดที่สอง
แต่สิ่งที่เกิดขึ้นก็คือเนื่องจากเอาต์พุตของมันไม่ได้ไปที่เทอร์มินัลgrepบัฟเฟอร์มัน นั่นคือมันไม่ได้เขียนจนกว่ามันจะสะสมเพียงพอ (4096 bytes ในการทดสอบของฉันกับ grep GNU)
สิ่งที่หมายถึงคือgrepจะไม่ออกก่อนที่จะเขียนข้อมูล 8192 ไบต์ดังนั้นอาจมีบางบรรทัด
ด้วย GNU grepคุณสามารถทำให้มันออกได้เร็วขึ้นโดยใช้--line-bufferedซึ่งบอกให้เขียนบรรทัดทันทีที่พบโดยไม่คำนึงว่าจะไปที่เทอร์มินัลหรือไม่ ดังนั้นgrepจะออกเมื่อพบบรรทัดที่สอง
แต่ด้วย GNU grepคุณสามารถใช้-m 1แทนได้เช่น @terdon แสดงซึ่งดีกว่าเมื่อออกจากการแข่งขันนัดแรก
หากคุณgrepไม่ใช่ GNU grepคุณสามารถใช้sedหรือawkแทน แต่tac เป็นคำสั่ง GNU ผมสงสัยคุณจะพบว่าระบบที่มีtacที่grepไม่ได้เป็น grepGNU
tac file | sed "/$pattern/!d;q" # BRE
tac file | P=$pattern awk '$0 ~ ENVIRON["P"] {print; exit}' # ERE
บางระบบต้องtail -rทำสิ่งเดียวกันกับที่ GNU tacทำ
โปรดทราบว่าสำหรับไฟล์ปกติ (หาได้) tacและtail -rมีประสิทธิภาพเพราะอ่านไฟล์ย้อนหลังพวกเขาไม่เพียงแค่อ่านไฟล์ในหน่วยความจำอย่างเต็มที่ก่อนที่จะพิมพ์ย้อนกลับ (เป็นวิธีการที่@ slmหรือtacไฟล์ที่ไม่ใช่ปกติ) .
ในระบบที่ค่าtacมิได้tail -rที่มีตัวเลือกเดียวที่จะดำเนินการย้อนหลังอ่านด้วยมือกับการเขียนโปรแกรมภาษาเช่นperlหรือการใช้งาน:
grep -e "$pattern" file | tail -n1
หรือ:
sed "/$pattern/h;$!d;g" file
แต่นั่นหมายถึงการค้นหาการแข่งขันทั้งหมดและพิมพ์ครั้งสุดท้ายเท่านั้น