AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 751665
Accepted
achhainsan
achhainsan
Asked: 2023-07-17 16:30:02 +0800 CST2023-07-17 16:30:02 +0800 CST 2023-07-17 16:30:02 +0800 CST

Selecione tudo entre dois timestamps em um arquivo de log

  • 772
awk '/10:..:/, /13:..:/' server.log > /tmp/awktmp

Eu tentei este comando como alguém me deu. Funcionou para mim encontrar logs entre 10:00 e 13:00, mas não entendo completamente.

Por favor, diga-me uma solução elegante, se você tiver um. Lembre-se de que os servidores remotos são mínimos e não possuem utilitários avançados.

O que eu não entendo aqui é'/10:..:/, /13:..:/'

  • Eu entendo 10:..que significa 10e :corresponde exatamente a 2 dígitos.
  • Mas o que :significa outro?

Suponho que as barras sejam para colocar expressões regulares como fazemos no JavaScript regex. Não tenho 100% de certeza sobre isso.

Atualização 1:

A hora está na segunda coluna, no formatoHH:MM:SS

Atualização 2:

sed -n -e '/8:..:../,/9:..:../p' application.log > /tmp/sedtmp

Eu tentei isso, mas isso também está mostrando logs de arquivos 07:57:47.

Atualização 3

Os logs nem sempre contêm o carimbo de data/hora em cada linha. Algumas linhas não contêm nenhum carimbo de data/hora. Como você superou esse problema? Eu estupidamente usei awk e perdi todas as linhas que não tinham valor de tempo nelas. Existe uma maneira de evitar esse problema?

Assim é o que quero dizer.

2023-08-07 09:20:35 0123456789 INFO  CustomerLogoutResource:95 - Entering logout api.
2023-08-07 09:20:35 0123456789 ERROR AppExceptionMapper:87 - Exception has been thrown by container
2023-08-07 09:20:35 0123456789 ERROR AppExceptionMapper:555 - Unchecked Exception
java.lang.NullPointerException
    at NullPointerExceptionExample.printLength(NullPointerExceptionExample.java:3)
    at NullPointerExceptionExample.main(NullPointerExceptionExample.java:8)
regular-expression
  • 4 4 respostas
  • 843 Views

4 respostas

  • Voted
  1. Paul_Pedant
    2023-07-17T16:54:31+08:002023-07-17T16:54:31+08:00

    O padrão /10:..:/corresponde aos dígitos 10, dois separadores de :e quaisquer dois caracteres entre eles. Portanto, corresponderá a um horário (em qualquer lugar na linha de entrada) como 10:35:22. Mas também corresponderia a uma linha contendo This10:ZZ:Camels, portanto, não é um teste muito bom.

    Um padrão melhor pode ser /10:[0-5][0-9]:[0-5][0-9]/, que verifica se os minutos e segundos estão no intervalo de 00 a 59. Mas também pode ser útil verificar se os horários estão em um campo específico, ou se há espaços em branco ao redor, ou se estão (inclusive) próximos ao início do registro. Você pode postar algumas linhas de entrada de amostra para que possamos dizer melhor o que é necessário.

    Ter dois padrões separados por uma vírgula "liga" a correspondência quando o primeiro padrão é detectado e "desliga" a correspondência quando o segundo padrão é detectado. Ele corresponderá a todas as linhas entre esses eventos (inclusive), mesmo que não contenham nenhuma data.

    Isso é muito diferente do padrão único /1[0-2]:[0-5][0-9]:[0-5][0-9]/, que corresponderia apenas a linhas individuais entre 10:00:00 e 12:59:59, em qualquer ordem em que estivessem.

    • 8
  2. Best Answer
    Stéphane Chazelas
    2023-07-17T17:36:17+08:002023-07-17T17:36:17+08:00

    Esse tipo de abordagem falha em encontrar as linhas para 11:00se 13:00não houver log entre 10:00 e 11:00 e relataria todas as linhas depois 14:00se não houvesse log entre 13:00 e 14:00 (e havia pelo menos um entre 10 e 11).

    O melhor para esse tipo de coisa é fazer comparação lexical do tempo contra os limites.

    Por exemplo, se a hora estiver no terceiro campo:

    awk '$3 >= "10:00:00" && $3 < "13:00:00"'
    

    Se você não sabe onde está a hora na linha, você pode fazer:

    perl -lne 'print if /\b\d\d:\d\d:\d\d\b/ &&
                          $& ge "10:00:00" &&
                          $& lt "13:00:00"'
    

    Ou:

    LC_ALL=C awk 'match($0, /[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/) && \
                    (t = substr($0, RSTART, 8)) >= "10:00:00" && \
                    t < "13:00:00"'
    

    Aqueles relatam as linhas que possuem um carimbo de data/hora no intervalo. Se você tiver linhas sem carimbos de data/hora entre as linhas com carimbos de data/hora e quiser que sejam relatados, poderá usar a beginning-condition, end-condition {action}abordagem como na sua pergunta, mas novamente usar a comparação em vez da correspondência regex ou fazer a troca de estado manualmente para continuar excluindo o limite superior :

    LC_ALL=C awk -v beg=10:00:00 -v end=13:00:00 '
      match($0, /[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/) {
        t = substr($0, RSTART, 8)
        if (t >= end) selected = 0
        else if (t >= beg) selected = 1
      }
      selected'
    
    • 8
  3. Olivier Dulac
    2023-07-17T17:16:59+08:002023-07-17T17:16:59+08:00

    o padrão awk:

    /regA/,/regB/
    

    será verdadeiro desde a primeira linha correspondente a regA, até a primeira linha correspondente a regB. E, como sempre, quando algo corresponde a uma expressão: se não houver { actions }após a expressão para especificar quais ações executar quando corresponder, a ação padrão é: imprima a linha onde a expressão é verdadeira.

    Agora eles escolheram:

    /10:..:/, /13:..:/
    

    para ter (um pouco) mais certeza de que você corresponde a 10:mm:ss e não a hh:10:ss. (Eles fazem isso assumindo que qualquer citação de hora será : hh:mm:ss, e que não há ':' antes da hora ... isso nem sempre é verdade, dependendo do formato de data usado. E como dito nos comentários, também pode combinar com outras coisas.

    Se você sabe que o início das linhas é sempre:

    YYYY-MM-DDThh:mm:ss+hh:mm 
    # For exemple:
    # 2023-07-17T11:14:02+02:00 , which is following internationnal recommendations
    # of displaying date and time (and timezone)
    

    Você pode combinar mais de perto com:

    /^2023-07-17T10:/,/^2023-07-17T13:/
    

    e certifique-se de corresponder apenas a partir do início (^) da linha e não onde quer que essas coisas possam aparecer na linha.

    • 1
  4. varsock
    2023-07-18T23:30:47+08:002023-07-18T23:30:47+08:00

    Aqui está uma solução possível que seleciona logs entre dois timestamps em um arquivo de log. Este script supõe que o arquivo de log tenha colunas separadas por espaços e a segunda coluna contém o carimbo de data/hora no formato HH:MM:SS. Pode não ser o mais elegante, mas pelo menos é legível.

    awk -F" " '$2 >= "09:00:00" && $2 <= "12:00:00"' server.log
    
    • -F" "define o separador de campo como um caractere de espaço.
    • $2refere-se ao segundo campo em cada linha do arquivo de entrada (os campos são separados por espaços neste caso).
    • >= "09:00:00"verifica se o valor do segundo campo é maior ou igual a "09:00:00".
    • &&um operador lógico que combina condições. Significa "e"
    • $2 <= "12:00:00"verifica se o valor do segundo campo é menor ou igual a "12:00:00".
    • sever.logé o seu arquivo de entrada

    Verificação da solução

    Para um server.logque se parece com isto:

    2023-07-18 08:55:32 - Log entry 1
    2023-07-18 09:10:15 - Log entry 2
    2023-07-18 10:30:47 - Log entry 3
    2023-07-18 11:45:02 - Log entry 4
    2023-07-18 12:05:21 - Log entry 5
    2023-07-18 13:20:33 - Log entry 6
    

    Saída:

    [get@me test]$ awk -F" " '$2 >= "09:00:00" && $2 <= "12:00:00"' server.log
    2023-07-18 09:10:15 - Log entry 2
    2023-07-18 10:30:47 - Log entry 3
    2023-07-18 11:45:02 - Log entry 4
    
    • 1

relate perguntas

  • Como remover alguns caracteres após uma partida?

  • Processe arquivos Unicode com BOM corretamente com ferramentas POSIX

  • Por que a expressão regular não corresponde à entrada com o comando sed [duplicado]

  • Converter senha com caracteres especiais para uso com script esperado

  • menos: várias condições de filtro com AND

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve