Существует ли команда, объединяющая `tee` и `grep` таким образом, чтобы в конвейере часть tee могла направлять совпадения в файл?

Существует ли команда, объединяющая `tee` и `grep` таким образом, чтобы в конвейере часть tee могла направлять совпадения в файл?

Я хочу вытащить несколько фрагментов из файла или, по крайней мере, следить за фрагментами в файле журнала, если они должны появиться, но я не хочу настраивать несколько tail | grepсеансов. Вместо этого я хотел бы просто отслеживать вывод каждого grep.

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

Например, команда может выглядеть примерно так:

tail -f /var/log/syslog | teegrep cron1 -f CRON | teegrep cloud-init2 -f CLOUD-INIT

Выводом будут файлы CRON и CLOUD-INIT, а все остальное в конце концов пойдет на stdout. Только совпадения для строк 'cron1' и 'cloud-init2' окажутся в соответствующих файлах.

Может быть, это уже часть команды, а я просто не знал об этом. Или, возможно, просто какая-то хитрость bash/zsh, которая сделает то же самое. В любом случае: есть ли команда, которая объединяет teeи grepтаким образом, что в конвейере часть tee может направлять совпадения в файл?

решение1

Предположим, что оболочка имеет подстановки процессов >(...):

tail -f /var/log/syslog | 
tee >(grep cron1 >CRON) | 
tee >(grep cloud-init2 >CLOUD-INIT)

Это приведет tailк созданию данных для первого teeв конвейере. teeДанные будут дублироваться и одна копия будет отправлена ​​следующему tee, а другая — в процесс замены. Этот процесс замены будет работать grepс данными, поступающими из , teeи результат будет отправлен в файл CRON.

Последний этап трубопровода будет работать аналогичным образом.


В оболочке, где замены процессов недоступны, например /bin/sh, awkили sedмогут быть использованы.

С awk:

tail -f /var/log/syslog | 
awk '{ print }
     /cron1/       { print >"CRON" }
     /cloud-print/ { print >"CLOUD-INIT" }'

С помощью sed(обратите внимание, что мы должны убедиться, что выходные файлы не существуют, поскольку wкоманда sedвсегда добавляет данные в файл):

rm -f CLOUD CLOUD-INIT

tail -f /var/log/syslog | 
sed -e '/cloud/w CLOUD' \
    -e '/cloud-print/w CLOUD-INIT'

Связанный контент