tail -f log | perl -e 'while (<>) { print "src=$1 dst=$2\n" if $_ =~ /src=([^\s]+) dst=([^\s]+)/; }'
Example line from syslog file:
Aug 1 10:25:50 10.10.10.1 id=firewall sn=XXXX time="2012-08-01 14:35:18 UTC" fw=x.x.x.x pri=6 c=1024 m=537 msg="Connection Closed" f=11 n=195273698 src=x.x.x.x:60246:X3: dst=x.x.x.x:443:X6:host.domain.com proto=tcp/https sent=181793 rcvd=649678
Eu quero fazer um
$ tail -f /var/log/log.log | SOMETHING
Isso retornará
"src=x.x.x.x dst=x.x.x.x"
No plainspeak, quero poder extrair campos específicos do texto. Eu não quero selecionar esses campos com base em um número de campo (posição na linha) porque a ordem das coisas pode mudar um pouco com o sistema que gera esse arquivo, portanto, não funciona.
Aberto a sugestões, mas preferiria que fosse um de uma linha.
tail -f log | perl -e 'while (<>) { print "src=$1 dst=$2\n" if $_ =~ /src=([^\s]+) dst=([^\s]+)/; }'
sed 's/^.*\(src=[0-9.][0-9.]*\).*\(dst=[0-9.][0-9.]*\).*$/ /'
Veja Extraindo um regex correspondido com 'sed' sem imprimir os caracteres adjacentes
grep tem uma opção --line-buffered
que permite seguir tail -f
tail -f /var/log/messages | grep --line-buffered 'src=[0-9.]+\s+dst=[0-9.]+'
não é tão bonito, mas outra solução implementada com o awk:
tail -f /var/log/log.log | awk 'FS="src=" { print "src="$2 }' | awk 'FS=":" { print $1$4 }''
Atualização: editada como uma linha para tail -f
Ou, melhorando um pouco sobre o warlOck:
tail -f log | perl -n -e 'print "$1 $2\n" if /(src=[^\s]+) (dst=[^\s]+)/;'
(Ainda não descobri como comentar uma resposta ...)