Se você usar tail -f
para completar 2 ou mais arquivos, o comando mostrará os dados linha por linha e gerará o nome do arquivo toda vez que a origem dos dados for alterada.
Usando isso, você pode escrever um script para mesclar a saída intercalada da cauda de acordo com o timestamp mantendo cada linha até ver uma linha do outro arquivo com um registro de data e hora posterior.
Por exemplo, usando dois arquivos de log padrão ( /var/log/messages
e /var/log/cron
) que no meu sistema têm o mesmo formato para o registro de data e hora no início da linha (por exemplo, Jun 9 02:55:01
), você pode fazer o seguinte: / p>
tail -f /var/log/messages /var/log/cron |
awk '
BEGIN { num[0] = 0; num[1] = 0; }
/^==> /{
file = $2; aa = file~/messages/?0:1; bb = 1-aa;
aanum = num[aa]; bbnum = num[bb];
next }
/^$/{ next }
{ "date --date \"" $1 " " $2 " " $3 "\" +%s" | getline date
lines[aa,aanum] = $0
dates[aa,aanum++] = date
maxes[aa] = date
minmax = maxes[aa]
if(maxes[bb]<minmax)minmax = maxes[bb]
i = 0; j = 0;
while(1){
aaok = (i<aanum && dates[aa,i]<=minmax)
bbok = (j<bbnum && dates[bb,j]<=minmax)
if(aaok && bbok){
if(dates[aa,i]<=dates[bb,j]){
print lines[aa,i]; dates[aa,i++] = ""
}else{
print lines[bb,j]; dates[bb,j++] = ""
}
}else if(aaok){
print lines[aa,i]; dates[aa,i++] = ""
}else if(bbok){
print lines[bb,j]; dates[bb,j++] = ""
}else break
}
i = 0
for(j = 0; j<aanum;j++)
if(dates[aa,j]!=""){
dates[aa,i] = dates[aa,j]; lines[aa,i++] = lines[aa,j]
}
aanum = num[aa] = i
i = 0
for(j = 0; j<bbnum;j++)
if(dates[bb,j]!=""){
dates[bb,i] = dates[bb,j]; lines[bb,i++] = lines[bb,j]
}
bbnum = num[bb] = i
}'
O awk vira entre os 2 arquivos quando vê o cabeçalho ==>
do arquivo da cauda. Ele mantém dados, em 4 matrizes, separadamente para cada arquivo, chamados arbitrariamente de aa
e bb
e numerados 0 e 1. dates
contém o registro de data e hora (em segundos da época), lines
mantém a linha de registro de entrada , num
contém a contagem de linhas e maxes
a data mais alta de um arquivo. Os dois primeiros arrays são bidimensionais indexados por arquivo (0 ou 1) e contagem de linhas retidas.
Conforme cada linha de log é lida, o registro de data e hora é convertido em segundos e salvo em uma nova entrada no final de dates
, e a linha também é salva. O mínimo das duas datas atuais é definido em minmax
. Todos os dados armazenados são digitalizados e impressos de acordo com a ordem de registro de data e hora até este mínimo. As entradas impressas são limpas e, no final do loop while, as matrizes são comprimidas para remover essas entradas limpas.