Como extrair logs entre dois registros de data e hora, a linha pode ou não iniciar com data e hora

3

Como extrair logs entre dois registros de data e hora, a linha pode ou não iniciar com data e hora. Eu estou tentando abaixo e é apenas extrair as linhas que começam com datetime apenas. O formato de data e hora é 2014-04-07 23:00

$ awk \
  '$0 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]/
      {
        if ($1" "$2 >= "2014-04-07 23:00")     p=1;
        if ($1" "$2 >= "2014-04-08 02:00")  p=0;
      }
    p { print $0 }' log

Aqui estão os dados da minha amostra:

2014-04-07 22:59:10.001 agaggagag  
gagagg 
2014-04-07 23:40:33.345 aegsgssdh  
wqtqttqtqtq  
post  
agggsdgg  
2014-04-08 01:00:54.777 ggsdgwettwetewt  
cvdgwetegdkiytitityi  
error 
2014-04-08 02:02:22.009 qwwqtwtwebbcbewdhshsdh  
asgsaftewtewt  
1253536443755475  
2014-04-08 10:55:34.934 etwtewtewppip  
jklhlljkjvncncmmm  
sghywywywywyw  

Eu quero extrair todos os dados entre 2014-04-07 23:00 e 2014-04-08 02:00

    
por Krish 04.12.2016 / 20:42

3 respostas

0

O RE na correspondência de padrões começa com ^ , que liga a expressão ao início da linha. Se você quiser combinar sua expressão em qualquer lugar, é necessário removê-la.

Suas declarações if... assumem que os campos de data / hora estão em $1 e $2 , que também são (por definição) não necessariamente verdadeiros. Tente isso em vez disso (não foi testado porque não tenho uma amostra dos seus dados)

awk '
    {
        if (match($0, /\<[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]\>/))
        {
            s = substr($0, RSTART, RLENGTH)            
            if (s >= "2014-04-07 23:00") p=1
            if (s >= "2014-04-08 02:00") p=0
        }
    }
    p { print $0 }
' log

Saída de dados de amostra

2014-04-07 23:40:33.345 aegsgssdh
wqtqttqtqtq
post
agggsdgg
2014-04-08 01:00:54.777 ggsdgwettwetewt
cvdgwetegdkiytitityi
error
    
por 05.12.2016 / 01:32
0

Altere o início do script para

$ awk \
  '$0 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]/ \
      {
           ︙

ou

$ awk \
  '$0 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]/    {
           ︙

Atualmente, seu script tem três declarações:

  1. Se a linha corresponder a /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]/ , imprima-a (ação padrão).
  2. Para todas as linhas (condição padrão), defina p para 1 se $1 $2 estiver dentro do intervalo e 0 se não for.
  3. Se p for diferente de zero, imprima a linha.

Então, todas as linhas que parecem um carimbo de data e hora (baseado no seu regexp) é impresso com base na declaração 1. E cada linha que contém um carimbo de data e hora dentro do intervalo de seleção é impresso com base na interação entre as afirmações 2 e 3.

Obviamente, você deseja vincular a condição 1 e a instrução 2 juntas.

    
por 05.12.2016 / 23:04
0

Eu criei um script simples para o seu propósito. Verifique se isso é útil para você

[upkar@server2 one]# cat logxtract.sh

L1=$(grep -n "2014-04-07 23:[0-9][0-9]" log | awk -F":" '{print $1}')

L2=$(grep -n "2014-04-08 02:[0-9][0-9]" log | awk -F":" '{print $1}')

sed -n $L1,"$L2"p log

Saída do script

[upkar@server2 one]# sh logxtract.sh

2014-04-07 23:40:33.345 aegsgssdh

wqtqttqtqtq

post

agggsdgg

2014-04-08 01:00:54.777 ggsdgwettwetewt

cvdgwetegdkiytitityi

error

2014-04-08 02:02:22.009 qwwqtwtwebbcbewdhshsdh
    
por 25.01.2017 / 14:03