Melhor maneira de incrementar números em uma linha no Linux

Melhor maneira de incrementar números em uma linha no Linux

Eu tenho uma linha com muitas entradas entre as quais também está o tempo.

 ('DEFAULT',17,NULL,'2014-07-14 10:30:00','Something','2014-07-14 06:30:00',1),('DEFAULT',26,NULL,'2014-07-14 12:00:00','Something2,'2014-07-14 11:00:00',1),...

Eu gostaria de aumentar cada vez em algumas horas. no formato 24h. Por exemplo 10:30:00se tornaria 15:30:00.

Qual é a melhor ferramenta universal para este trabalho? Estou pensando em termos de:

  1. utilitários de sistema como awk, sed..& qualquer outra coisa que eu não saiba

  2. vim

  3. linguagens de script como bashou python`

Qual seria a maneira canônica de fazer isso?

Responder1

Só para esclarecer:

vimé um utilitário de sistema (um editor de texto) na maioria dos sistemas *nix. awk, sede bashsão linguagens (ou ferramentas, dependendo do contexto) que você pode usar para analisar e alterar texto.

Para que você precisa aumentar o tempo e com que frequência você precisará incrementá-lo? Esses fatores determinam quais ferramentas você deseja usar. De qualquer forma, este é um esforço de várias partes, ASSUMINDO QUE ISSO NÃO É SQL:

  1. Você primeiro está combinando strings parciais dentro de uma string. Você pode usar awk, sed, ou grep -e, com uma regex, para extrair essas substrings.

  2. Quando você tiver esses valores, você os converterá em números inteiros (ou, se estiver usando uma linguagem mais completa como python, poderá convertê-los em valores de data e hora usando uma biblioteca). Você terá que fazer as contas necessárias (e validação, se aplicável) para alterar esses valores.

  3. Finalmente, você adicionará os valores substituídos na linha e salvará o arquivo alterado.

Honestamente, porém, isso parece sql, então pode ser muito mais fácil usar oferramentas integradasnesse idioma para alterar esses valores.

Responder2

Existem algumas boas dicas emesta respostasugerindo um caminho de menor resistência usando uma linguagem de script como Perl, Python, Ruby, etc., que permite a mistura de operações matemáticas e de correspondência.

Aqui está um hack rápido com Perl:

$ echo '2014-12-05 10:00:10, 1234, 2015-02-01 09:12:24' | perl -pe \
    's/(\d{4}-\d{2}-\d{2} )(\d{2})(:\d{2}:\d{2})/join("",$1,$2+3,$3)/eg'
2014-12-05 13:00:10, 1234, 2015-02-01 12:12:24
$

Neste exemplo simplista, a classe de caracteres de dígito ( \d) seguida pelo indicador de repetição (por exemplo {2}) é usada para capturar componentes posicionais da data e fazemos aritmética cegamente no campo de hora. Este tipo de solução só é apropriada quando você conhece seus dados bem o suficiente para garantir que a aritmética simplista no campo das horas não fará com que o dia seja transferido.

Revisitando este problema para resolver a aritmética correta de data/hora quando o campo horas transborda conforme solicitado por @Lieven, o módulo principal Perl Time::Piece(Perl> 5.8) pode ser usado:

$ echo '2014-12-05 22:00:00, 1234, 2015-02-01 09:12:24' | \
    perl -MTime::Piece -pe \
        's/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/( \
            Time::Piece->strptime($1, "%Y-%m-%d %T") \
            + (60*60*3))->strftime("%Y-%m-%d %T")/eg'
2014-12-06 01:00:00, 1234, 2015-02-01 12:12:24
$

Este exemplo de entrada foi atualizado para mostrar o tratamento adequado dos valores de horas transferidos para o dia seguinte. Ele puxa o Time::Piecemódulo na linha de comando, combina a data e hora da entrada, converte em Time::Pieceobjetos para realizar a aritmética de data/hora e, em seguida, transforma novamente no formato de saída desejado.

informação relacionada