ログを見て、プログラムが3回試みたが失敗したことを確認したいと思います。
tail -f file.log | grep --line-buffered program\ failed\ string
行数がgrep
3になったらエラーを返したいです。
どうすればいいですか?
答え1
アッストリームをスキャンする素晴らしいツールです。
あなたの例とは異なり、終了するまでログを表示するにはすべての行を表示する必要があると思います。grepエラー行のみが表示されます。
tail -f file.log | awk '
BEGIN {
count = 0
}
{
print($0)
if ($0 ~ /program failed/) {
count++
if (count == 3) {
exit(1)
}
}
}
'
awkコードを次に移動できます。tail.awktail -f file.log | awk -f tail.awk
ご希望の場合はお電話ください。
同様に、より簡潔な形で:
tail -f file.log | awk '1; /program failed/ && ++count == 3 { exit 1 }'
答え2
誰かがPythonの代替案を好む場合に備えて:
#!/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)