La mejor manera de incrementar números en una línea en Linux

La mejor manera de incrementar números en una línea en Linux

Tengo una línea con muchas entradas entre las que también está el tiempo.

 ('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),...

Me gustaría incrementar cada vez unas pocas horas. en formato 24h. Por ejemplo 10:30:00se convertiría en 15:30:00.

¿Cuál es la mejor herramienta universal para este trabajo? Estoy pensando en términos de:

  1. utilidades del sistema como awk, sed..y cualquier otra cosa que no sepa

  2. vim

  3. lenguajes de scripting como basho python`

¿Cuál sería la forma canónica de hacerlo?

Respuesta1

Solo para aclarar:

vimes una utilidad del sistema (un editor de texto) en la mayoría de los sistemas *nix. awk, sedy bashson lenguajes (o herramientas, según el contexto) que puede utilizar para analizar y modificar texto.

¿Para qué necesita incrementar el tiempo y con qué frecuencia deberá incrementarlo? Estos influyen en las herramientas que querrás utilizar. En cualquier caso, este es un esfuerzo de varias partes, SUponiendo que ESTO NO ES SQL:

  1. Primero estás haciendo coincidir cadenas parciales dentro de una cadena. Puede usar awk, sedo grep -e, con una expresión regular, para extraer esas subcadenas.

  2. Cuando tenga esos valores, los convertirá a números enteros (o si está usando un lenguaje más completo como Python, es posible que pueda convertirlos en valores de fecha y hora usando una biblioteca). Tendrá que hacer los cálculos necesarios (y la validación, si corresponde) para modificar esos valores.

  3. Finalmente, agregará los valores reemplazados en la línea y guardará el archivo modificado.

Honestamente, esto parece sql, por lo que podría ser mucho más fácil usar elherramientas incorporadasen ese idioma para alterar esos valores.

Respuesta2

Hay algunos buenos consejos enesta respuestasugiriendo un camino de menor resistencia utilizando un lenguaje de programación como Perl, Python, Ruby, etc. que permite mezclar operaciones matemáticas y de coincidencia.

Aquí hay un truco rápido con 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
$

En este ejemplo simplista, la clase de carácter dígito ( \d) seguida del indicador de repetición (p. ej. {2}) se utiliza para capturar componentes posicionales de la fecha y hacemos aritmética ciega en el campo de la hora. Este tipo de solución sólo es apropiada cuando conoce sus datos lo suficientemente bien como para garantizar que la aritmética simplista en el campo de horas no provoque que el día se retrase.

Al revisar este problema para abordar la aritmética correcta de fecha/hora cuando el campo de horas se desborda como lo solicita @Lieven, Time::Piecese puede usar el módulo principal de Perl (Perl>5.8):

$ 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
$

Esta entrada de ejemplo se ha actualizado para mostrar un manejo elegante de los valores de horas que se trasladan al día siguiente. Extrae el Time::Piecemódulo en la línea de comandos, compara la fecha y hora de la entrada, lo convierte en Time::Pieceobjetos para realizar aritmética de fecha/hora y luego vuelve a encadenarlo al formato de salida deseado.

información relacionada