Возможно ли отфильтровать вывод tail?

11

Я хотел бы привязать файл, но только выходные строки, в которых есть определенная строка. Это возможно?

Абе Мисслер
источник

Ответы:

32

используйте grep. Он построен только для этой цели.

Чтобы найти строки из хвоста / var / log / syslog, в которых есть «cron», просто запустите:

tail -f /var/log/syslog | grep cron

И так как он принимает что-либо через stdin, вы можете использовать его и в выходных данных любой другой команды, выполняя конвейерную обработку так же, как описано выше (используя символ |).

Райан Х
источник
8
Хотя это по существу правильно, важно понимать, что grepбуферизуется, когда он используется неинтерактивно, например, когда он является частью более длинного конвейера. GNU grep 2.5.1 предлагает --line-bufferedвозможность обойти эту проблему, когда исключение grep из конвейера не вариант. (Когда я говорю, что grep будет буферизовать, я имею в виду, что вы не увидите вывод, пока буфер не достигнет чего-то вроде 4k.)
kojiro
В дополнение к предыдущему комментарию "tail -f" в современном Linux будет работать в цикле, ожидая большего ввода в файле системного журнала. Чтобы команда действительно закончила с существующим содержимым файла, опустите ключ -f: tail / var / log / syslog | grep cron
Gnudiff
7
tail -f /var/log/messages | grep "myfilterword"

Надеюсь, это поможет.

Пабло
источник
4

Вот пара других идей, которые, хотя и не так просты, могут предложить некоторую интересную дополнительную гибкость:

Во-первых, вы можете фильтровать с помощью awk вместо grep:

tail -f /var/log/messages | awk '/myfilterword/'

это работает точно так же, как в примере с использованием grep. Вы можете расширить это, используя силу awk, например:

tail -f /var/log/messages | \
awk '/myfilterword/ { for (i=6; i<=NF; i++) printf("%s ", $i); printf("\n")}'

который будет печатать с шестого по последнее поле вывода (поля разделены пробелами)

Другая похожая идея заключается в использовании perl однострочного:

tail -f /var/log/messages | perl -ne "/myfilterword/ and print"

это работает так же, как grep. Может быть, вы хотите счетчик номера строки и только 6-е поле? Как насчет этого:

tail -f /var/log/messages | \ 
perl -lane "/myfilterword/ and printf \"%6d %s\n\",++\$a,\$F[6]"

Очевидно, что все эти виды вещей можно сделать и с помощью других инструментов, но я хотел бы проиллюстрировать, что здесь есть несколько забавных способов использовать более универсальные языки, такие как awk или perl.

Фил Холленбек
источник
+1 отличная проработка того, как расширяться дальше, чем grep!
Пабло
2

Стоит отметить еще один прием, если у вас есть файл CSV с заголовками, которые вы хотите опустить, например:

% cat data.txt
fruit        dessert        calories
Apple        Pie            770
Banana       Pudding        625
Cherry       Cobbler        990
% tail -n +2 data.txt
Apple        Pie            770
Banana       Pudding        625
Cherry       Cobbler        990

Не имеет значения , сколько времени на входе tailесть, +n -2опускают первую строку.

JeffG
источник