tail -f แต่มีหมายเลขบรรทัด


21

ฉันพยายามที่จะดูว่ามีกี่ครั้งที่foo barปรากฏขึ้น/var/log/foo.logภายในระยะเวลาโดยพลการบนเซิร์ฟเวอร์ระยะไกล แต่ไม่มีอะไรที่ฉันได้ลองมาแล้ว

ฉันมีสคริปต์ตัวจับเวลาแล้วที่ฉันใช้เพื่อติดตามว่ามันได้รับมานานแค่ไหนตั้งแต่ฉันเริ่ม tailing /var/log/foo.logและตอนนี้ฉันก็อยากจะบอกว่ากี่ครั้งที่foo barปรากฏในเอาท์พุทเทลด์

ฉันค้นหา google แต่ฉันไม่พบสิ่งใดที่เกี่ยวข้องภายใน 10 หน้าแรกของผลลัพธ์

นี่คือสิ่งที่ฉันได้ลองด้วยผลลัพธ์ที่น่าผิดหวัง:

## works on local machine, but doesn't work as expected on remote
tail -f /var/log/foo.log | grep foo\ bar | sed '='

## works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | cat -n -

##  works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | awk -F'\n' '{printf "[%d]> ", NR; print $1}'

ฉันยังพยายามที่จะเขียนบทสคริปที่จะทำหน้าที่เหมือนtail -fแต่ฉันไม่ได้ทำอะไรแบบนั้น

บันทึก

รีโมตเซิร์ฟเวอร์กำลังรัน coreutils เวอร์ชันเก่ากว่าและการอัพเกรดเป็นตัวเลือก แต่ไม่ได้เป็นวิธีการแก้ปัญหาที่ต้องการ


2
มันไม่ได้ผลในทางใด? ลองเลือกที่จะ--line-buffered grepหรือtail -f ... | awk '/foo bar/{print ++n, $0}'
Stéphane Chazelas

ทำไมมันไม่ทำงานในระยะไกล ตัวอย่าง:tail -f /var/log/log.log | awk '{ printf "[%d]> %s\n", NR+1 ,$0; fflush(stdout); }'

คำตอบ:


29
tail -f | nl

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

ที่กล่าวว่า

tail -f | grep -n pattern

ทำงานสำหรับฉันเช่นกัน การกำหนดหมายเลขเริ่มต้นอีกครั้งตั้งแต่เริ่มต้นของ "tailing" แทนที่จะเริ่มต้นของไฟล์บันทึกทั้งหมด


grep รุ่นที่ทำงานบนเซิร์ฟเวอร์ไม่มี-nตัวเลือก
Alexej Magura

อย่างไรก็ตามมีตัวเลือกยาว--line-number: tail -f /var/log/foo.log | grep foo\ bar --line-numberใช้ได้!
Alexej Magura

1
นั่นเป็นที่น่าสนใจ - ฉันยังไม่ได้ตรวจสอบ POSIX เป็นเช่นนี้ แต่ GNU grep manpage says: -n ระบุโดย POSIX
เตอร์

16

ฉันคิดว่ามันดีกว่า ..

less -N +F <filepath>

2
คุณช่วยอธิบายได้ไหมว่าทำไมคุณถึงคิดว่ามันดีกว่า
Navigatron

นี่คือการแก้ไขขนาดใหญ่ฉันกำลังคืนค่า
Adam Eberlin

3
แสดงหมายเลขบรรทัดที่ใช้อ้างอิงไฟล์ทั้งหมด หาง -f | nl แสดงหมายเลขบรรทัดที่ใช้อ้างอิงการส่งออกแรกของหาง
rafaelvalle

นี้เป็นอย่างมากที่มีประโยชน์และที่อยู่ของ OP ชื่อแต่ไม่ได้เป็นของคำถาม พวกเขาต้องการทราบจำนวน X ที่ปรากฏในไฟล์: P
Timmah

6

นอกจากนี้คุณยังสามารถไพพ์เอาต์พุตไปยังlessมันมีคุณสมบัติหมายเลขบรรทัด-Nซึ่งจะอนุญาตให้คุณเลื่อนไปมาผ่านล็อก

$ tail -f /var/log/foo.log | less -N

ตัวอย่าง

  1 Jan 17 22:11:58 greeneggs fprintd[4323]: ** Message: entering main loop
  2 Jan 17 22:12:01 greeneggs su: (to root) saml on pts/5
  3 Jan 17 22:12:28 greeneggs fprintd[4323]: ** Message: No devices in use, exit
  4 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Git | personal_repo | Checking for remote changes...
  5 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git rev-parse HEAD
  6 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git ls-remote --heads --exit-code "ssh://sam@sparkleshare.jake      
  6 8us.org/home/sam/SparkleShare/personal_repo.git" master
  7 Jan 17 22:12:58 greeneggs gnome-session[1876]: X11 forwarding request failed on channel 1
  8 Jan 17 22:12:58 greeneggs gnome-session[1876]: 22:12:58 | Git | personal_repo | No remote changes, local+remote: 532213be48cce3b93cb177d409faa      
  8 03b71d0cfa5
  9 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Pinging tcp://notifications.sparkleshare.org:443/
 10 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Received pong from tcp://notifications.sparkleshare.org:443/

หมายเหตุ:ให้สังเกตการส่งออก คุณอาจจะชอบหรือไม่ชอบคุณสมบัตินี้ แต่มันจะใช้เวลานานและสับมันเพื่อให้พวกเขาดำเนินการต่อในบรรทัดถัดไป แต่ยังคงรักษาหมายเลขบรรทัดที่สอดคล้องกัน ฉันพบว่าคุณสมบัตินี้มีค่าเมื่อแยกไฟล์บันทึกที่กว้าง! คุณสามารถเห็นผลของคุณสมบัตินี้ในบรรทัด 6และ8


นี่ไม่ชัดเจน ชื่อไฟล์อยู่ที่ไหนระบุ? มันควรจะชี้แจงสังเกตว่าการส่งออกจะมีหมายเลขตั้งแต่วันที่ 1 เริ่มต้นด้วยช่วง 10 tailสายของชื่อไฟล์เป็นที่เป็นพฤติกรรมปกติของ ในฐานะที่เป็นสายยาวพฤติกรรมที่สลับภายในใช้less -S
ILMostro_7

2

เพื่อ grep บรรทัดใหม่เฉพาะในไฟล์บันทึกที่มาพร้อมกับหมายเลขบรรทัดคุณสามารถทำได้:

{
  initial_lines=$(wc -l)
  tail -n +1 -f | awk -v NR="$initial_lines" '/pattern/{print NR": "$0}'
} < file.log

(ด้วยmawkคุณจะต้องเพิ่ม-Winteractiveตัวเลือกเพื่อป้องกันการป้อนข้อมูล (!) การบัฟเฟอร์)

wc -lอ่านบรรทัดที่มีอยู่แล้วและนับ (อักขระขึ้นบรรทัดใหม่ซึ่งหมายความว่ายังคงใช้ได้แม้ว่าบรรทัดสุดท้ายจะยังไม่เต็ม) จากนั้นเราtail -fที่เหลือ (เริ่มจากที่wcหยุดอ่าน) และบอกawkว่าหมายเลขบรรทัดของ คนแรกที่เห็น


การเลือกlเป็นชื่อตัวแปรทำให้ฉันเหล่ตามองที่ $ l คิดว่าเป็น$1^^ (แต่ฉันรู้ (และเชื่อถือได้ 100%) คุณฉันอ่านซ้ำและเห็นความจริง) เพียงเพื่อความอยากรู้อยากเห็น: เพื่อหลีกเลี่ยง "สภาพการแข่งขัน" บางอย่างระหว่างwc -lและtail -f(หากไฟล์เติบโตอย่างรวดเร็วหนึ่งอาจทิ้งบางบรรทัดและทำให้ NR เริ่มจากจำนวนที่ไม่ถูกต้อง) เป็นไปได้ไหมที่จะข้าม$lบรรทัดแทน? (และจะมีข้อ จำกัด อะไรบ้างที่จะให้หาง-nอยู่ใน posix & in gnu?) อาจจะมีไฟล์ระดับกลางชั่วคราว?
Olivier Dulac

@OlivierDulac tail -n +1(อ่านอะไรจากตำแหน่งเริ่มต้น) ที่อยู่ที่เกี่ยวข้องกับสภาพการแข่งขัน มันจะอ่านบรรทัดที่ไม่ได้อยู่ในไฟล์ในเวลาที่wc -lถูกยกเลิกจากตำแหน่งที่แน่นอนwcทิ้งไว้ ดังนั้น NR จะมีตำแหน่งที่ถูกต้องโดยไม่คำนึงถึงจำนวนบรรทัดที่ถูกเขียนในระหว่างwcสิ้นสุดและtailเริ่มต้น ถ้าคุณบอกtailให้เริ่มจากตำแหน่งที่สัมพันธ์กับจุดสิ้นสุดของไฟล์ที่คุณมีปัญหา
Stéphane Chazelas

โอ้การขัดจังหวะ: แน่นอนข้อมูลที่รวบรวมไว้ใน stdin ในขณะที่ไม่มีสิ่งใดอ่านได้ (ระหว่างจุดสิ้นสุดของ wc จนถึงจุดเริ่มต้นของศีรษะ) ... ฉันควรตระหนักว่า ขอบคุณ. ตอนนี้ฉันเห็นว่าทำไมคุณ "<file" ฉลาดตามปกติ :)
Olivier Dulac

1
@OlivierDulac เกี่ยวกับข้อ จำกัด (ซึ่งไม่ได้ใช้กับtail -n +1ที่นี่) สำหรับไฟล์ปกติการใช้งานส่วนใหญ่ไม่มีหนึ่งอย่างที่พวกเขาสามารถเริ่มจากจุดสิ้นสุดและseekกลับจนกว่าพวกเขาจะพบ newline ที่ n โดยไม่ต้องเก็บค่ามากกว่าหนึ่ง buf ของข้อมูลในหน่วยความจำ สำหรับอินพุตที่ไม่สามารถค้นหาได้นั่นคือที่ที่คุณสามารถพบเจอได้ในขีด จำกัด POSIX ต้องการการใช้งานเพื่อให้สามารถจัดเก็บอย่างน้อย 10 x LINE_MAX ไบต์ (LINE_MAX อย่างน้อย 2048) หาง GNU ไม่มีข้อ จำกัด นอกจากหน่วยความจำ AFAIK
Stéphane Chazelas

0

หากคุณต้องการนับตั้งแต่ต้นคุณต้องใช้ grep -n เพื่อใช้กับทุกบรรทัด

 tail -f -n100000000 filename.log | grep -n '' 

หากคุณต้องการแสดงเฉพาะ 10 รายการล่าสุดฉันคิดว่าคุณสามารถจัดไฟล์ใหม่ได้:

 tail -f -n100000000 filename.log | grep -n '' | tail -n10

อันแรกมีประโยชน์ แต่แสดงผลลัพธ์มากเกินไป ฉันไม่รู้ว่าทำไมตัวที่สองไม่ทำงาน


Tail ไม่มี "แสดงทุกบรรทัด" ดังนั้น 100000000 ของฉัน
Martin Cleaver

1
tail -n +1 -fเพื่อหางจากจุดเริ่มต้น
Stéphane Chazelas

1
อันที่สองไม่ทำงานเพราะสิ่งที่ถูกต้องที่สุดtailไม่สามารถส่งออกอะไรได้จนกว่าจะเห็นบรรทัดสุดท้ายของอินพุต (จะรู้ได้อย่างไรว่าบรรทัดสุดท้ายที่ 10 คืออะไร) ซึ่งจะไม่เกิดขึ้นอย่างที่tail -fไม่เคยหยุดนิ่ง
Stéphane Chazelas

-1

คำสั่งcat -n [filename] | tailจะได้รับการนับจำนวนอย่างรวดเร็วและแสดงระเบียนล่าสุดหากนั่นคือสิ่งที่คุณกำลังมองหา

-fสวิทช์ทำให้ถาวรจนกว่าจะหลบหนี - ซึ่งจริงๆไม่ได้เสียงที่ใช้บังคับในสถานการณ์ของคุณหรือซ้ำซ้อน

wc -l [filename] จะได้รับจำนวนบรรทัดในเป้าหมาย

wc -l [filenameprefix]* จะนับบรรทัดทั้งหมดในไฟล์ทั้งหมดที่ตรงกับรูปแบบและแม้กระทั่งรายงานผลรวมสรุปในตอนท้าย

รายละเอียดที่สมบูรณ์มากขึ้นสามารถให้การตอบสนองที่สมบูรณ์มากขึ้น


-1

เป็นอาร์กิวเมนต์nหรือ--lines(ใช้วิธีที่แตกต่างกันเล็กน้อยดูด้านล่าง):

$ tail -f -n 25 /path/to/file.txt

$ tail -f --lines=25 /path/to/file.txt

ดูความช่วยเหลือด้วย:

$ tail --help

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