จะใช้ตัวกรองกับเอาต์พุตแบบเวลาจริงของ 'tail -f' ได้อย่างไร


60
tail -f path

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

วิธีการนี้


1
การทำเครื่องหมายคำตอบตามที่ได้รับการยอมรับจะช่วยให้ผู้อื่นที่อ่านคำถามของคุณและคำตอบของพวกเขารู้ว่าคำตอบใดน่าจะช่วยพวกเขาได้หากพวกเขามีคำถามหรือปัญหาที่คล้ายกัน คุณสามารถกลับไปที่คำถามก่อนหน้านี้โดยคลิกที่ชื่อผู้ใช้ของคุณ
Dennis Williamson

คำตอบ:


84

ด้วย Unix คุณสามารถไพพ์เอาท์พุทของโปรแกรมหนึ่งไปยังอีกโปรแกรมหนึ่งได้

ดังนั้นในการกรองหางคุณสามารถใช้ grep:

tail -f path | grep your-search-filter

แต่สมมุติว่าคุณมี 100 เส้นที่ท้าย (ท้ายไฟล์) และบรรทัดเหล่านี้คือบรรทัดที่คุณต้องการกรอง วิธีแก้ปัญหาของคุณ
TraderJoeChicago

1
หากคุณต้องการค้นหาไฟล์ 100 บรรทัดสุดท้ายให้ลองใช้ tail -100 path | grep xxx
AddersUK

15

คำตอบสั้น ๆ : tail -f somefile | grep somepattern

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

แต่tail -fและtail -Fพิมพ์ออกมาเป็นกลุ่มบรรทัดแรกซึ่งมักจะเป็นที่ไม่พึงประสงค์ในกรณีใช้งานนี้ดังนั้นในกรณีนี้เพิ่ม-n0

tail -F -n0 somefile | grep somepattern

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

tail -F -n0 somefile | grep somepattern

แต่คุณตัดสินใจที่จะใช้สิ่งที่ชอบawkหรือcutเพื่อประมวลผลผลลัพธ์เพิ่มเติม

tail -F -n0 somefile | grep somepattern | awk '{print $3}'

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

ในกรณีนี้คุณสามารถบอกgrepให้ทำการสร้างบรรทัด stdout เสมอโดยใช้--line-bufferedตัวเลือก

tail -F -n0 somefile | grep --line-buffered somepattern | ...

--line-bufferedอย่างไรก็ตามคำสั่งส่วนใหญ่ไม่ได้อะนาล็อกของ ในกรณีของเครื่องมือที่เขียนสคริปต์ได้มากกว่านี้คุณสามารถใช้ฟังก์ชั่นเพื่อล้างข้อมูลที่ส่งออก (เช่น. in awk, ฟังก์ชั่นคือfflush(), ซึ่งใช้ชื่อเดียวกันกับสำเนา C, เครื่องมือเช่น Perl และ Python มีบางสิ่งที่คล้ายกัน)

ด้วยการที่cutคุณชอบคุณจะไม่มีโชค ... แต่คุณอาจลองค้นหาunbufferซึ่งฉันคิดว่ามีบางอย่างที่expectToolchain จัดให้(ฉันไม่เคยใช้)

ฉันหวังว่าคุณจะพบว่ามีประโยชน์นี้

ไชโยคาเมรอน


ฉันขอขอบคุณคำอธิบายว่าทำไมสิ่งนี้จึงทำงานในโหมด line-buffered นั่นเป็นข้อมูลเชิงลึกที่ยอดเยี่ยมขอบคุณ
Green

2

และคุณสามารถใช้หลายท่อและ greps และแยกสิ่งต่าง ๆ ด้วย grep -v, รับ case insensitivity ด้วย grep -i, ฯลฯ

ie: tail -100f / var / log / messages | grep -V ACPI | grep -i ata

เริ่ม tailing 100 บรรทัดจากจุดสิ้นสุดและเก็บไว้ก่อนแยกบรรทัดใด ๆ กับ ACPI จากนั้นแสดงบรรทัดด้วย ata, ATA หรือการผสมผสานของเหล่านั้น

อีกวิธีที่สะดวกคือตัวเลือก ABC สำหรับบรรทัดหลัง, ก่อนหน้าและบริบท (บรรทัดก่อนและหลัง)

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