tempo de atraso de cinco primeiros com arquivo de log com script de shell

3

Arquivo de entrada

Mar 19 06:10:16 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:00:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)
Mar 19 14:41:26 ip-172-2-0-53 sendmail[29483]: v2JLfNFN029481: to=<[email protected]>,<[email protected]>, delay=00:00:03, xdelay=00:00:03, mailer=esmtp, pri=151738, relay=ifaded-com.mail.p...ction.outlook.com. [xx.xxx.x.x], dsn=2.0.0, stat=Sent (<[email protected]> [InternalId=31288836753166, Hostname=ERGsDGddssdD5.namprd07.prod.outlook.com] 8924 bytes in 0.309, 28.142 KB/sec Queued mail for delivery)
Mar 19 06:10:26 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:20:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)

Eu tentei seguir o comando

 cat logh.txt | grep -E -o " delay=.[^,]*|^[^ip]+" 

Eu quero descobrir o tempo de atraso do top 5 com a data como posso resolver este problema com o comando llinux. Estou recebendo o seguinte resultado

Mar 19 06:10:16
 delay=00:00:15
Mar 19 14:41:26
 delay=00:00:03
Mar 19 06:10:26
 delay=00:20:15

Saída desejada

  Mar 19 06:10:26 delay=00:20:15
  Mar 19 06:10:16 delay=00:00:15
  Mar 19 14:41:26 delay=00:00:03
    
por Mahesh Phate 12.04.2017 / 14:26

2 respostas

2

Você precisará de vários passes. Aqui está uma solução que usa sed , sort , head e cut para dar a você o top 5 na ordem desejada.

sed -e 's/^\([A-Za-z]\{3\} \{1,2\}[0-9]\{1,2\} \{1,2\}\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\).* \(delay=\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\)\).*/  /' | sort -nr | head -n5 | cut -d\  -f2-

Com sua entrada fornecida, isso é emitido:

Mar 19 06:10:26 delay=00:20:15
Mar 19 06:10:16 delay=00:00:15
Mar 19 14:41:26 delay=00:00:03

(Presume-se que sua entrada esteja no formato de log que você forneceu, e que seja apenas linhas alimentadas com os dados que você deseja. Um grep adicional no início pode ser necessário.)

O que está fazendo

Vamos dividi-lo.

sed

sed significa o Stream EDitor. É usado rotineiramente para aplicar expressões regulares a fluxos de texto.

expressão regular de sed

's/^\([A-Za-z]\{3\} \{1,2\}[0-9]\{1,2\} \{1,2\}\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\).* \(delay=\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\)\).*/  /'

Isso é muito bom, mas precisa ser, para evitar retrocesso catastrófico .

Estamos usando as substituições do Regex. Para ver o que está fazendo em detalhes, experimente o Regex101 . Por enquanto, saiba que é necessária a entrada:

Mar 19 06:10:16 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:00:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)
Mar 19 14:41:26 ip-172-2-0-53 sendmail[29483]: v2JLfNFN029481: to=<[email protected]>,<[email protected]>, delay=00:00:03, xdelay=00:00:03, mailer=esmtp, pri=151738, relay=ifaded-com.mail.p...ction.outlook.com. [xx.xxx.x.x], dsn=2.0.0, stat=Sent (<[email protected]> [InternalId=31288836753166, Hostname=FOOBAR1.namprd07.prod.outlook.com] 8924 bytes in 0.309, 28.142 KB/sec Queued mail for delivery)
Mar 19 06:10:26 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:20:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)

e converte para

000015 Mar 19 06:10:16 delay=00:00:15
000003 Mar 19 14:41:26 delay=00:00:03
002015 Mar 19 06:10:26 delay=00:20:15

correspondência regex sed

^\([A-Za-z]\{3\} \{1,2\}[0-9]\{1,2\} \{1,2\}\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\).* \(delay=\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\)\).*

Primeiramente, combinamos explicitamente os componentes de data; vamos precisar disso para a saída, depois. Nós então encontramos e combinamos o atraso e seus componentes de temporização individualmente; o atraso, você queria na sua saída. Os componentes de tempo, nós precisaremos depois, para ordenar.

substituição de regex de sed

  

No lado de substituição do regex, pegamos os componentes de tempo que pegamos, e os concatenamos sem o delimitador ":" que eles originalmente tinham. Isso é importante, já que vamos usá-los para sort depois. Após os componentes de temporização, anexamos a string date e toda a string de delay original; nós os queremos depois que classificarmos.

classificar

sort -nr

Como nossa entrada agora começa com um número decimal em vez de um registro de data e hora, podemos usar o modo numérico de sort , especificado com o sinalizador -n .

Por padrão, sort classifica em ordem crescente, o que coloca os maiores valores no final. Como isso significaria processar all da saída de sort para encontrar os maiores N valores, usamos o sinalizador -r da classificação para reverter a ordem de saída; Agora, os maiores valores serão exibidos primeiro e podemos usar head em vez de "tail".

Nossa saída, neste ponto, é assim:

002015 Mar 19 06:10:26 delay=00:20:15
000015 Mar 19 06:10:16 delay=00:00:15
000003 Mar 19 14:41:26 delay=00:00:03

cabeça

head -n5

Neste ponto, nossa entrada terá os maiores valores primeiro e já sabemos que queremos os 5 maiores valores. Portanto, usamos o parâmetro head de -n para informar a head quantos valores desejamos.

Como neste exemplo não temos mais de 5 valores, ainda obtemos toda a saída em que fomos alimentados.

002015 Mar 19 06:10:26 delay=00:20:15
000015 Mar 19 06:10:16 delay=00:00:15
000003 Mar 19 14:41:26 delay=00:00:03

corte

cut -d\  -f2-

Como não precisamos mais dela, precisamos remover a chave numérica de classificação inserida com sed no primeiro passo. Para isso, recorremos a cut , o que nos permite escolher quais campos queremos de cada linha fornecida.

Usamos o parâmetro -d do cut para dizer qual é o nosso separador de campo, nosso delimitador. Como o separador de campos é o espaço em branco, precisamos escapar com \ , o que nos dá -d\ .

Da perspectiva de cut , isso divide a linha 002015 Mar 19 06:10:26 delay=00:20:15 em 002015 Mar 19 06:10:26 delay=00:20:15 .

Para especificar quais campos desejamos, usamos -f . Como queremos todos, exceto o primeiro campo, usamos -f2- , o que nos dá a saída desejada:

Mar 19 06:10:26 delay=00:20:15
Mar 19 06:10:16 delay=00:00:15
Mar 19 14:41:26 delay=00:00:03
    
por 12.04.2017 / 15:31
0
perl -lane '
   print join $", /\sdelay=\K(\S+)(?=,)/, splice(@F, 0, 3), /\s\K(delay=\S+)(?=,)/;
' | sort -t: -k 1,1nr -k 2,2nr -k 3,3nr | cut -d\  -f2- | head -n 5
    
por 12.04.2017 / 16:15