tail -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}'
ステファン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

私にも機能します。番号付けは、ログファイル全体の先頭ではなく、「末尾」の先頭から再開されます。


サーバーで実行されているgrepのバージョンには-nオプションがありません。
アレクセイマグラ14年

ただし、長いオプションがあります--line-numbertail -f /var/log/foo.log | grep foo\ bar --line-number動作します!
アレクセイマグラ14年

1
それは興味深いです-POSIX自体はチェックしていませんが、GNU grepのマンページには:-nはPOSIXで指定されています。
ペテルフ14年

16

これは良いと思います。

less -N +F <filepath>

2
なぜあなたがより良いと思うのか説明できますか?
Navigatron

これは大きな編集で、元に戻しています。
アダムエバリン

3
ファイル全体を参照する行番号を表示します。テール-f | nlは、tailの最初の出力を参照する行番号を示します。
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行目でこの機能の効果を確認できます。


これは不明です。ファイル名はどこに指定されていますか?出力はファイル名の最後の10行から始まる1から番号付けされていることに注意してください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 -ltail -f(ファイルが早く伸びる場合、1は、いくつかの行を破棄してもよく、したがってNRが間違った番号から始まる)を、それがスキップすることが可能である$l代わりにラインを?(そして-n、posixとgnuのtailにはどのような制限がありますか?)。一時的な中間ファイルがあるのでしょうか?
オリビエデュラック

@OlivierDulac tail -n +1(開始位置から何でも読む)は、競合状態の問題に対処します。wc -l終了した時点でファイルになかった行を、wc残った正確な位置から読み取ります。したがって、NRは、wc終了とtail開始の間に何行が書き込まれたかに関係なく、正しい位置になります。tailファイルの終わりに対して相対的な位置から開始するように指示した場合、問題が発生します。
ステファンシャゼラス

ああ、興味深い:実際、データは何も読み取らない間(wcの終わりから頭の始まりまで)にstdinに蓄積されます。THX。なぜあなたは「<file」なのかわかりました。賢い、いつものように:)
オリビエデュラック

1
(には適用されません制限について@OlivierDulac、tail -n +1彼らは端から開始し、できるよう定期的にファイルのため、ここでは)、ほとんどの実装は1を持っていないseek複数のbufの価値を保存することなく、彼らはn番目の改行を見つけるまで、バックメモリ内のデータ。シークできない入力の場合は、そこに限界があります。POSIXでは、実装が少なくとも10 x LINE_MAXバイト(LINE_MAXは少なくとも2048)を格納できる必要があります。GNUテールは、メモリ私の知る限り以外には制限がありません
ステファンChazelas

0

最初から番号を付けたい場合は、すべての行に適用するためにgrep -nが必要です。

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

その後、最後の10個だけを表示したい場合は、ファイルをリテールできると思います。

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

最初のものは便利ですが、出力が多すぎます。なぜ2番目のものが機能しないのか分かりません。


テールには「すべての行を表示する」機能がないため、100000000
Martin Cleaver

1
tail -n +1 -f最初から尾に。
ステファンシャゼラス

1
2番目のものは機能しません。なぜなら、右端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
OPは行数ではなく行番号を必要とします。
robbat2
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.