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:00
se tornaria 15:30:00
.
Qual é a melhor ferramenta universal para este trabalho? Estou pensando em termos de:
utilitários de sistema como
awk
,sed
..& qualquer outra coisa que eu não saibavim
linguagens de script como
bash
ou 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
, sed
e bash
sã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:
Você primeiro está combinando strings parciais dentro de uma string. Você pode usar
awk
,sed
, ougrep -e
, com uma regex, para extrair essas substrings.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.
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::Piece
módulo na linha de comando, combina a data e hora da entrada, converte em Time::Piece
objetos para realizar a aritmética de data/hora e, em seguida, transforma novamente no formato de saída desejado.