पूंछ -f, लॉग के बाद लाइन ब्रेक डालें 3 सेकंड के लिए निष्क्रिय है?


14

जब एक कर tail -f error.log, प्रोग्राम एक लाइन ब्रेक के बाद कुछ भी नहीं 3 सेकंड के लिए फाइल करने के लिए किया गया है appened सम्मिलित करने के लिए?

(जाहिर है, एक बार एक लाइन ब्रेक जोड़ दिए जाने के बाद, कोई अन्य लाइन ब्रेक को तब तक नहीं जोड़ा जाना चाहिए जब तक कि लॉग फाइल में टेक्स्ट की अन्य लाइन जोड़ नहीं दी जाती)

उदाहरण के लिए, इन पंक्तियों को 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

या जाने tail -fपीछा करते हैं और का उपयोग perlवहाँ 3 सेकंड के लिए कोई इनपुट अगर नई-पंक्तियों को सम्मिलित करने के:

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

वे मानते हैं कि आउटपुट स्वयं धीमा नहीं होता है (जैसे कि जब आउटपुट एक पाइप पर जाता है जो सक्रिय रूप से पढ़ा नहीं जाता है)।


यह मुझे यह पता लगाने की क्यों एक दूसरे वास्तव में कार्य करता :) काफी समय लगा
हॉब्स

मैंने पहली कोशिश की है, और यह हाथ से पहले सभी फ़ाइलों को मुद्रित करता है, इसलिए यह इष्टतम नहीं है। दूसरा एक आकर्षण की तरह काम करता है। मैंने "पूंछ -n 0 -f $ 1 |" विकल्प (एन 0) फ़ाइलों की पुरानी लाइनों को प्रदर्शित करने से बचने के लिए।
सेड्रिक

छोटा प्रश्न: मैं 10 सेकंड के बाद डैश (-------) की एक अतिरिक्त लाइन प्रदर्शित करने के लिए दूसरे समाधान में संशोधन कैसे कर सकता हूं? (मैंने कई तरीकों की कोशिश की है, लेकिन कुछ भी काम नहीं कर सकता है)
सेड्रिक

1
@Cedric, अपने पहले बिंदु के लिए संपादन देखें। आपकी दूसरी आवश्यकता पहले दृष्टिकोण के साथ आसान होगी।
स्टीफन चेज़लस

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)

बैश में, आप $SECONDSसमय अंतराल की गणना करने के लिए उपयोग कर सकते हैं । मुझे लगता है कि शेल शुरू होने के बाद से यह सेकंड की संख्या है, ऐसा नहीं है कि अंतर लेते समय यह मायने रखता है।
ilkachachu

@ilkachachu, या read -tया $TMOUT$SECONDSमें टूट गया है bashऔर mkshtime bash -c 'while ((SECONDS < 3)); do :; done'2 और 3 सेकंड के बीच रहेगा। यहां या (इसके साथ typeset -F SECONDS) के बजाय zsh या ksh93 का उपयोग करने के लिए बेहतर है
स्टीफन चेज़ेलस

@ स्टीफनचेज़लस, मुझे नहीं लगता कि यह उपयोग करने से अलग है date +%s। दोनों पूरे सेकंड में समय देते हैं, जिसका असर है कि अंतराल, कहते हैं, 1.9 से 4.0 3 पूर्ण सेकंड की तरह दिखता है, भले ही यह वास्तव में 2.1 हो। यह मुश्किल है कि अगर आप भिन्नात्मक सेकंड तक पहुँच नहीं सकते हैं तो चारों ओर काम करना मुश्किल है। लेकिन हाँ, उन्हें शायद व्यस्त रहने के बजाय यहाँ सोना चाहिए, और फिर read -tबस इस्तेमाल किया जा सकता है। यदि आप मैन्युअल रूप से सोते हैं, तो भी time bash -c 'while [[ $SECONDS -lt 3 ]]; do sleep 1; done'ठीक काम करता है।
ilkachachu

1
ksh93 और zsh उस के साथ ठीक हैं (zsh का उपयोग नहीं किया गया)। पूर्णांक $ SECONDS के साथ भी, सेटिंग SECONDS=0यह सुनिश्चित करती है कि $SECONDS1 सेकंड में 1 तक पहुंच जाएगी। इसके बजाय ट्रैक करने के लिए bashइसका उपयोग time()करने के साथ ऐसा नहीं $SECONDSहै gettimeofday()। मैंने कुछ समय पहले mksh, zsh और bash को बग की सूचना दी थी, केवल zsh तय किया गया था। (मुद्दे के साथ एक ही बात के बारे में अच्छी बात date +%s)। ध्यान दें कि यह यहाँ एक कामचलाऊ नहीं है, क्योंकि हम tail -fएक पाइप के उत्पादन से पढ़ रहे हैं ।
स्टीफन चेज़लस

+1 और बैश में एक "शॉर्टकट" है जो बाहरी उपकरणों या कमांड प्रतिस्थापन के बिना अंतर्निहित उपयोग printfकरने के लिए है :। dateprintf -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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.