tail -f, 로그가 3 초 동안 유휴 상태 인 후 줄 바꿈을 삽입 하시겠습니까?


14

를 할 때 tail -f error.log3 초 동안 파일에 아무것도 적용되지 않은 후 프로그래밍 방식으로 줄 바꿈을 삽입하는 방법은 무엇입니까?

(한 줄 바꿈을 추가 한 후에는 다른 줄의 텍스트를 로그 파일에 추가 할 때까지 다른 줄 바꿈을 추가하지 않아야합니다.)

예를 들어,이 행은 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
대화식으로 수행하는 경우 엔터 키를 여러 번 누르십시오. :)
와일드 카드

답변:


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'

그들은 출력 자체가 느려지지 않는다고 가정합니다 (출력이 활발하게 읽히지 않는 파이프로 갈 때).


왜 두 번째 것이 실제로 작동하는지 알아내는 데 오랜 시간이 걸렸습니다. :)
hobbs

첫 번째 파일을 사용해 보았고 모든 파일을 미리 인쇄했기 때문에 최적이 아닙니다. 두 번째는 매력처럼 작동합니다. "tail -n 0 -f $ 1 |"를 추가했습니다. 이전 파일 행을 표시하지 않으려면 옵션 (-n 0)을 사용하십시오.
Cedric

작은 질문 : 10 초 후에 추가 대시 줄 (-------)을 표시하도록 두 번째 솔루션을 어떻게 수정할 수 있습니까? (나는 여러 가지 방법을 시도했지만 아무 것도 만들 수 없다)
Cedric

1
@Cedric, 첫 번째 포인트 편집을 참조하십시오. 첫 번째 방법을 사용하면 두 번째 요구 사항이 더 쉬워집니다.
Stéphane Chazelas

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에서 손상되었습니다 . 2 ~ 3 초 동안 지속됩니다. 대신에 여기에 zsh 또는 ksh93을 사용하는 것이 좋습니다 (와 함께 )bashmkshtime bash -c 'while ((SECONDS < 3)); do :; done'typeset -F SECONDS
Stéphane 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는 이것으로 OK입니다 (zsh는 사용하지 않았습니다). 정수 $ SECONDS의 경우에도 설정 SECONDS=0$SECONDS정확히 1 초에 1에 도달 하도록합니다 . 대신 추적 bash하는 데 사용 하는 경우에는 그렇지 않습니다 . 얼마 전에 mksh, zsh 및 bash에 버그를보고했지만 zsh 만 수정되었습니다. (와 동일한 문제에 대한 좋은 지적 ). 우리는 파이프 를 통한 출력을 읽을 때 바쁜 루프가 아닙니다 . time()$SECONDSgettimeofday()date +%stail -f
Stéphane Chazelas

+1 및 Bash에는 외부 도구 나 명령 대체없이 printf에뮬레이션하기 위해 내장 기능을 사용하는 "바로 가기"가 있습니다. dateprintf -v t '%(%s)T' -1
David Foerster

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.