хвіст -f, але з номерами рядків


21

Я намагаюся побачити, скільки разів foo barз’являється /var/log/foo.logпротягом довільної кількості часу на віддаленому сервері, але нічого, що я намагався до цього часу, не спрацювало.

У мене вже є сценарій таймера, який я використовую, щоб відслідковувати, скільки часу минуло з моменту початку хвостової стрічки /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}'

Я навіть намагався написати сценарій sed, який би діяв так tail -f, але я зробив обмежений шлях до цього.

ПРИМІТКА

на віддаленому сервері працює старша версія coreutils, і оновлення - це варіант, але НЕ в жодному разі бажане рішення.


2
Яким чином це не працює? Спробуйте вибрати --line-bufferedваріант grep. Абоtail -f ... | awk '/foo bar/{print ++n, $0}'
Стефан Шазелас

Чому він не працює на дистанційному? Приклад: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

працює і для мене. Нумерація починається знову ж таки з початку "хвостики", а не з початку всього журналу.


версія grep, запущена на сервері, не має -nможливості.
Олексій Магура

Однак у нього є довгий варіант --line-number: tail -f /var/log/foo.log | grep foo\ bar --line-numberпрацює!
Олексій Магура

1
Це цікаво - я не перевіряв POSIX як такий, але GNU grep manpage каже: -n визначається POSIX .
петерф

16

Я думаю, що це краще ..

less -N +F <filepath>

2
Чи можете ви пояснити, чому ви вважаєте, що це краще?
Навігаторон

Це велика редакція, я ревертую.
Адам Еберлін

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

Щоб перемазати нові рядки лише у файлі журналу, оскільки вони походять зі своїм номером рядка, ви можете зробити:

{
  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?). Може, з тимчасовим проміжним файлом?
Олів'є Дулак

@OlivierDulac, tail -n +1(читайте що-небудь із стартової позиції) вирішує проблеми, пов'язані з умовами гонки. Він прочитає рядки, які не були у файлі на час wc -lприпиненого, з точного положення, яке wcйого залишили. Таким чином, NR матиме правильне положення незалежно від того, скільки рядків було написано між wcзакінченням і tailпочатком. Це якщо ви сказали tailпочати з якоїсь позиції відносно кінця файлу, у вас виникнуть проблеми.
Стефан Шазелас

о, інтерес: дійсно, дані накопичуються в stdin, поки нічого не читає (між кінцем wc до початку голови) ... я мав би це зрозуміти. Дякую. Тепер я бачу, чому ви "<файл". розумний, як завжди :)
Олів'є Дулак

1
@OlivierDulac, щодо обмежень (які не стосуються tail -n +1тут), для звичайних файлів більшість реалізацій не мають жодного, оскільки вони можуть починатися з кінця і seekназад, поки вони не знайдуть n-й новий рядок, не зберігаючи більше одного буфера. даних у пам'яті. Щодо вхідних даних, які не можна шукати, саме там ви можете зіткнутися з обмеженнями. 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

Перший зручний, але показує занадто багато результатів. Я не знаю, чому другий не працює.


У хвоста немає "показати всі лінії", отже, мій 100000000
Мартін Клівер

1
tail -n +1 -fдо хвоста від початку.
Стефан Хазелас

1
Другий не працює, тому що правий більшість tailнічого не може вивести, поки не побачить останній рядок свого вводу (як би він знав, який є останній 10-й рядок?), Який ніколи не відбудеться так, як tail -fніколи не припиняється.
Стефан Хазелас

-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
ОП хоче номер рядків, а не кількість рядків.
robbat2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.