grep และหาง -f


28

เป็นไปได้ที่จะทำtail -f(หรือคล้ายกัน) ในไฟล์และgrepในเวลาเดียวกัน? ฉันจะไม่รังเกียจคำสั่งอื่น ๆ เพียงแค่มองหาพฤติกรรมแบบนั้น

คำตอบ:


46

ใช้ GNU tailและ GNU grepฉันสามารถ grep a tail -fโดยใช้ไวยากรณ์ตรงไปข้างหน้า:

tail -f /var/log/file.log | grep search_term

นี่เป็นวิธีการแก้ปัญหาที่ทำงานร่วมกับการใช้งานอื่น ๆ ของทั้งสองยูทิลิตี้ไม่เพียง แต่การใช้งานของ GNU
Kusalananda

7

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

$ (echo foo; sleep 5; echo test; sleep 5) | grep test

จะไม่มีอะไรเกิดขึ้นเป็นเวลา 5 วินาทีจากนั้น grep จะส่งออก "test" ที่ตรงกันแล้วห้าวินาทีต่อมามันจะออกเมื่อกระบวนการ piped ทำ


7

เพิ่ม--line-bufferedไปยังgrepและนั่นอาจลดความล่าช้าสำหรับคุณ มีประโยชน์มากในบางกรณี

tail -f foo | grep --line-buffered bar

2
มีประโยชน์เมื่อเอาต์พุตของgrepไม่ไปที่เทอร์มินัล (เปลี่ยนเส้นทางไปยังไฟล์ประเภทอื่น) การบัฟเฟอร์บรรทัดเป็นค่าเริ่มต้นเมื่อเอาต์พุตไปยังเทอร์มินัลดังนั้นมันจะไม่สร้างความแตกต่างเลย โปรดทราบว่าตัวเลือกนั้นเป็น GNU เฉพาะ
Stéphane Chazelas


2

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

 tail -Fn+0 /path/to/file|grep searchterm

นี่ถือว่า GNU หางและ grep สนับสนุนรายละเอียดจาก manpage หาง (GNU coreutils, เหมืองคือ v8.22) [ https://www.gnu.org/software/coreutils/manual/coreutils.html] :

 -F     same as --follow=name --retry
 -n, --lines=K
         output the last K lines, instead of the last 10; or use -n +K to output
         starting with the Kth.
         If  the first character of K (the number of bytes or lines)
         is a '+', print beginning with the Kth item from the start
         of each file, otherwise, print the last K items in the file.
         K may have a multiplier suffix: b 512, kB 1000, K 1024, MB
         1000*1000, M 1024*1024, GB 1000*1000*1000, G 1024*1024*1024,
         and so on for T, P, E, Z, Y.

  With --follow (-f), tail defaults to following the file descriptor,
  which means that even if a tail'ed file is renamed, tail will
  continue to track its end.  This default behavior is  not  desirable
  when  you  really  want  to  track the actual name of the file, not
  the file descriptor (e.g., log rotation).  Use --follow=name in
  that case.  That causes tail to track the named file in a way that
  accommodates renaming, removal and creation.

ดังนั้นส่วนหางของคำสั่งของฉันเท่ากับtail --follow --retry --lines=+0ที่ที่อาร์กิวเมนต์สุดท้ายชี้นำให้เริ่มต้นที่จุดเริ่มต้นข้ามเส้นศูนย์


1
tail -f access | awk '/ADD/{print $0}'

ใช้ข้างต้นฉันใช้มันมักจะ


0

คุณสามารถใช้ netcat เพื่อ grep ผลลัพธ์ของ tail -f เนื่องจากผลลัพธ์ใหม่เข้ามาค่อนข้างง่าย

sudo nc -s localhost -l -p 1337 | grep ssh


tail -f /var/log/file.log | nc 127.0.0.1 1337

ชุดนี้ grep ฟังผลลัพธ์สำหรับอินพุตที่มาจากพอร์ต 1337
คำสั่งที่สองไพพ์เอาต์พุตของ tail -f ไปยัง netcat และส่งออก localhost 1337 หากต้องการทำภายในเครื่องคุณต้องสลับ ttys สำหรับคำสั่งสองชุด หรือใช้บางอย่างเช่นหน้าจอ


0

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


ตกลง เพื่อทดสอบสิ่งนี้ให้เปิดหน้าต่างสองบาน เรียกใช้tail -fในหน้าต่างหนึ่งและtail -f logfile | grep patternในหน้าต่างอื่น บรรทัดที่มีpatternไม่ปรากฏในหน้าต่างทั้งสองในเวลาเดียวกัน ฉันเคยเห็นเส้นปรากฏขึ้น 30 วินาทีในบางโอกาสซึ่งเป็นเรื่องที่น่ารำคาญ
Stefan Lasiewski

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