5

Я пытаюсь фильтровать вывод одного файла журнала в отдельные файлы журнала на основе фильтра grep.

tail -f test.log | tee>(grep "Error"> error.log)>(grep "Warning" "> warning.log)

Таким образом, все записи "Ошибка" находятся в одном файле, а все записи "Предупреждение" находятся в отдельном файле.

Я знаю, что это работает в принципе, потому что, если я использую cat вместо tail, я получаю правильный вывод файла, но не могу отслеживать изменения в реальном времени (что мне нужно, потому что я наблюдаю журналы вывода из активно запущенных тестов)

Кроме того, если я удаляю переадресацию файлов «>» из команд grep, то она корректно выводит отдельные выходы grep на консоль; однако, я хочу записанный файл также.

Ответ:

При записи в файл выходные данные grep буферизировались. Использование egrep с опцией --line-buffer исправило поведение.

Новая команда выглядит так:

tail -f test.log | tee>(egrep --line-buffered "ERROR"> error.log)>(egrep --line-buffered "WARNING"> warning.log)

2 ответа2

0

@ Райан, спасибо за размещение ответа на ваш вопрос.
Еще один (универсальный) способ настройки буферизации для каждой строки - использовать команду stdbuf :

tail -f test.log | tee >(stdbuf -oL grep "ERROR" > error.log) >(stdbuf -oL grep "WARNING" > warning.log)

Вот выдержка из man stdbuf:

SYNOPSIS
   stdbuf OPTION... COMMAND
...
   -o, --output=MODE
          adjust standard output stream buffering
...
   If MODE is 'L' the corresponding stream will be line buffered.
....
EXAMPLES
   tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq
   This will immedidately display unique entries from access.log
0

Это может быть проще, если вы используете более одной строки для этого. Вы можете написать скрипт bash:

#!/bin/bash

tail -f test.log | while read line; do
    if echo "$line" | grep -q "Error"; then
        echo "$line" >> error.log
    elif echo "$line" | grep -q "Warning"; then
        echo "$line" >> warning.log
    # The following is in case you want to print out lines that do not match 
    else
        echo "$line"
    fi
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .