Vuelva a formatear la fecha a la marca de tiempo de Unix en la tabla csv

Vuelva a formatear la fecha a la marca de tiempo de Unix en la tabla csv

Tengo un .csvarchivo que contiene la fecha y la hora en el formato 01/20/2016 23:53:01de la primera columna. Mis columnas están separadas por punto y coma, es decir

01/21/2016 03:03:01;18616;0;1
01/21/2016 03:13:01;29040;36553;2

EnENTONCESEncontré el comando bash

date -d '06/12/2012 07:21:22' +"%s" 

que funciona para lo que quiero. Ahora he estado intentando integrarme awkpara reemplazar la primera columna. encontré unrespuesta para un problema similar:

awk -F'"' -v OFS='"'  '$8 {cmd="date -d \""$8"\" +%FT%T%z"; cmd | getline $8; close(cmd)} 1' input.json

Que he tratado de adaptar a mis propios aportes. Pero he estado obteniendo una salida vacía.

Respuesta1

Finalmente lo esquivé mientras escribía la pregunta. Así que aquí está mi solución:

awk -F';' -v OFS=';'  '$1 {cmd="date -d \""$1"\" +%s"; cmd | getline $1; close(cmd)} 1' datetime.csv > unix.csv

Había sido la combinación de dos cosas: me faltaba el "encendido +%s"y había una línea discontinua en mi entrada.

Respuesta2

GNU date tiene una -fopción para convertir fechas leídas de un archivo, línea por línea. Si su archivo es largo, esto será más rápido que invocardate una vez por línea. La fecha debe estar sola en la línea; por lo tanto, el plan es aislar la primera columna ( cut -d \; -f 1), ejecutarla date -f -para realizar la conversión ypegarel resultado con las columnas restantes.

paste -d \; <(<input cut -d \; -f 1 | date -f - +%s) <(<input cut -d \; -f 2-)

Esto supone que su shell admitesustitución de procesos(ksh93, bash, zsh). Con Plain sh, en una variante de Unix que lo admita /dev/fd(la mayoría lo hace), puede usar la combinación aleatoria de descriptores de archivos:

<input cut -d \; -f 2- | {
  exec 3<&0
  <input cut -d \; -f 1 | date -f - +%s | paste -d \; - /dev/fd/3
}

Respuesta3

Mmmmm. Vale, esto fue hace un tiempo, pero creo que también puedo hacer una sugerencia.

Estoy bastante seguro de que ingresar al shell para llamar "fecha" para cada línea de su archivo puede ser un poco lento si tiene muchas líneas.

Iba a entrar en un script que escribí para procesar las entradas de la hoja de horas, extraído de Google Calendar, y generar algo de HTML para luego convertirlo en una factura en PDF. Pero luego se hizo demasiado largo hablando de eso. Así que sólo te daré el código para ahorrar en la lectura.

Estoy usando las funciones AWK gensub y mktime [https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html]. La función mktime espera la entrada en el formato de especificación de fecha "AAAA MM DD HH MM SS [DST]", por lo que su entrada debe cambiarse, que es donde entra en juego la función gensub. Esto es lo que tengo para usted...

awk -F';' -v OFS=';' '{ $1=mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)); } 1' datetime.csv > unix.csv

Haría esto de manera un poco diferente y generaría los argumentos individuales en una impresión en lugar de volver a escribir en el primer argumento. Un poquito más de autodocumentación;) TIMTOWTDI

awk -F';' -v OFS=';' '{ print mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)), $2, $3, $4; }' datetime.csv > unix.csv

Sé que el guión es un poco más detallado pero espero que tenga más rendimiento.

Espero que te ayude a ti o a cualquier otra persona que esté viendo lo mismo.

información relacionada