tail -f、ログが3秒間アイドルになった後に改行を挿入しますか?


14

を行うときにtail -f error.log、3秒間ファイルに何も適用されなかった後にプログラムで改行を挿入する方法は?

(明らかに、1つの改行が追加されたら、テキストの他の行がログファイルに追加されるまで、他の改行は追加されません)

たとえば、これらの行はerror.logに追加されます:

foo
bar
boo [[wait 4 seconds]]
2far
2foo
2bar
2boo [[wait 40 seconds]]
2far

これはコンソールの出力です:

foo
bar
boo

2far
2foo
2bar
2boo

2far

おそらく、私の中で機能を適応させることができaskubuntu.com/a/993821/158442、または使用tsの出力にタイムスタンプを追加し、タイムスタンプを処理するために
muru

1
対話的に行う場合は、Enterキーを何度も押すだけでよいことに言及する価値があります。:)
ワイルドカード

回答:


12

あなたは常に手動で実装することができますtail -f(ここで、コメントを外さない限り、ファイル全体をダンプするseek()ようにtail -n +1 -fperl、たとえば、

perl -e '
  $| = 1;
  # seek STDIN, 0, 2; # uncomment if you want to skip the text that is
                      # already there. Or if using the ksh93 shell, add
                      # a <((EOF)) after < your-file
  while (1) {
    if ($_ = <STDIN>) {
      print; $t = 0
    } else {
      print "\n"            if $t == 3;
      # and a line of "-"s after 10 seconds:
      print "-" x 72 . "\n" if $t == 10;
      sleep 1;
      $t++;
    }
  }' < your-file

または、3秒間入力がない場合tail -f、テーリングを実行しperlて改行を挿入します。

tail -f file | perl -pe 'BEGIN{$SIG{ALRM} = sub {print "\n"}} alarm 3'

これらは、出力自体が遅くならないことを前提としています(アクティブに読み取られないパイプに出力が送られる場合など)。


2番目のものが実際に機能する理由を理解するのに長い時間がかかりました:)
hobbs

最初のものを試しましたが、すべてのファイルを事前に印刷したので、最適ではありません。2番目は魅力のように機能します。「tail -n 0 -f $ 1 |」を追加しました ファイルの古い行を表示しないようにするオプション(-n 0)。
セドリック

小さな質問:10秒後に追加のダッシュ行(-------)を表示する2番目のソリューションを修正するにはどうすればよいですか?(私は複数の方法を試しましたが、何も機能させることはできません)
セドリック

1
@Cedric、最初のポイントの編集をご覧ください。最初のアプローチでは、2番目の要件が簡単になります。
ステファンシャゼラス

8

bash+ date解決策:

while IFS= read -r line; do        
    prev=$t         # get previous timestamp value
    t=$(date +%s)   # get current timestamp value
    [[ ! -z "$prev" ]] && [[ "$((t-prev))" -ge 3 ]] && echo ""
    echo "$line"    # print current line
done < <(tail -f error.log)

Bashでは、$SECONDS時間間隔をカウントするために使用できます。これは、シェルが開始されてからの秒数であり、違いを取るときに問題になるとは考えていません。
ilkkachu

@ilkkachu、またはread -tまたは$TMOUT$SECONDS中に壊れているbashmkshtime bash -c 'while ((SECONDS < 3)); do :; done'2〜3秒続きます。代わりに、ここで使用zshのかは、ksh93した方が良い(とtypeset -F SECONDS
ステファンChazelas

@StéphaneChazelas、を使用することと何の違いもないと思いますdate +%s。どちらも完全な秒で時間を与えます。これは、実際には2.1ですが、1.9から4.0までの間隔が3つの完全な秒のように見えるという効果があります。秒の小数部にアクセスできない場合は、回避するのは困難です。ただし、はい、おそらくビジーループの代わりにここでスリープする必要があり、その後read -tも同様に使用できます。手動でスリープしても、問題なくtime bash -c 'while [[ $SECONDS -lt 3 ]]; do sleep 1; done'動作します。
ilkkachu

1
ksh93とzshはそれで問題ありません(zshは使用しませんでした)。整数の$ SECONDSであっても、設定SECONDS=0により$SECONDS、正確に1秒で1に達することが保証されます。の代わりにをbash使用time()して追跡するため、これは当てはまりません。しばらく前にmksh、zsh、bashにバグを報告しましたが、zshだけが修正されました。(問題がと同じであるという良い点)。パイプ経由の出力から読み取っているので、ここではビジーループではないことに注意してください。$SECONDSgettimeofday()date +%stail -f
ステファンシャゼル

+1とBashには、組み込みの外部ツールやコマンドの置換なしでprintfエミュレートする「ショートカット」がありdateますprintf -v t '%(%s)T' -1
デビッドフォースター

6

Python解決策(動的な時間ギャップ引数を使用):

tailing_by_time.py 脚本:

import time, sys

t_gap = int(sys.argv[1])    # time gap argument
ts = 0
while True:
    line = sys.stdin.readline().strip()    # get/read current line from stdin
    curr_ts = time.time()                  # get current timestamp
    if ts and curr_ts - ts >= t_gap:
        print("")                          # print empty line/newline
    ts = curr_ts
    if line:
        print(line)                        # print current line if it's not empty

使用法:

tail -f error.log | python tailing_by_time.py 3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.