grep --line-buffered bis X Zeilen?

grep --line-buffered bis X Zeilen?

Ich beobachte ein Protokoll und möchte erkennen, wenn ein Programm drei Fehlversuche hatte:

tail -f file.log | grep --line-buffered program\ failed\ string

Wenn die Zeilenanzahl grep3 erreicht, möchte ich einen Fehler zurückgeben.

Wie kann ich das machen?

Antwort1

awkist ein großartiges Tool zum Scannen von Streams.

Ich bin davon ausgegangen, dass alle Zeilen angezeigt werden sollen, um das Protokoll anzuzeigen, bis es beendet wird, im Gegensatz zu Ihrem Beispiel mitgrepdie nur Fehlerzeilen anzeigen.

tail -f file.log | awk '
    BEGIN {
        count = 0
    }

    {
        print($0)

        if ($0 ~ /program failed/) {
            count++
            if (count == 3) {
                exit(1)
            }
        }
    }
'

Sie können den Awk-Code verschieben nachSchwanz.awkund rufen Sie an tail -f file.log | awk -f tail.awk, wenn Sie möchten.

Entsprechend in einer kompakteren Form:

tail -f file.log | awk '1; /program failed/ && ++count == 3 { exit 1 }'

Antwort2

Nur für den Fall, dass jemand eine Python-Alternative bevorzugt:

#!/usr/bin/env python2
# -*- encoding: ascii -*-
"""tail.py"""

import sys
import argparse
import time
import re

# Create a command-line parser
parser = argparse.ArgumentParser()

parser.add_argument(
    "-f", "--input-file",
    help="File to search through.",
    dest="input_file", type=str,
)
parser.add_argument(
    "-p", "--pattern",
    help="Regular expression to match.",
    default=r'.*',
    dest="pattern", type=str,
)
parser.add_argument(
    "-m", "--match-limit",
    help="Number of matches before exiting.",
    default=float(1),
    dest="match_limit", type=int,
)
parser.add_argument(
    "-q", "--quiet",
    help="Don't print matched lines.",
    default=False,
    dest="quiet", type=bool,
)

# Define the file-watching function
def watch_for_matches(file_handle, pattern, match_limit, quiet):

    # Count the number of matched lines
    matches_found = 0

    # Get the next line
    line = file_handle.readline()

    # Check to see if the limit has been reached
    while(matches_found < match_limit):

        # Match the line against the given regular expression
        if(line and re.search(pattern, line)):

            # Optionally print the matched line
            if not quiet:
                sys.stdout.write(line)

            # Increment the match counter
            matches_found += 1

        # Optionally wait for a moment 
        time.sleep(0.25)

        # Get the next line of input
        line = file_handle.readline()

    # If the match limit is reached, exit with an error
    sys.exit(1)

# Parse the command-line arguments
args = parser.parse_args()

# Execute the function
if args.input_file:
    with open(args.input_file, 'r') as file_handle:
        watch_for_matches(file_handle, args.pattern, args.match_limit, args.quiet)

# If no file is given, use standard input instead
else:
    watch_for_matches(sys.stdin, args.pattern, args.match_limit, args.quiet)

verwandte Informationen