
Fichero de entrada:Contiene 3 columnas y la tercera columna es la fecha en DD-MMM-YYYY
formato
de datos de muestra:
1232,abdc, 02-Jan-2014
4534,kdafh, 20-Feb-2014
364,asjhdk, 11-Jul-2012
salida requerida:
1232,abdc, 2014-01-02
4534,kdafh, 2014-02-20
364,asjhdk, 2012-07-11
usando la función fecha: date -d 20-DEC-2014 +%Y-%m-%d
lo usé el comando awk da error
¿Hay alguna otra manera?
Respuesta1
Una posible respuesta usando awk, asumiendo que el archivo de entrada es input-file.txt y el archivo de salida es output-file.txt:
awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d "$3" +%Y-%m-%d");}' input-file.txt > output-file.txt
Respuesta2
UsandoMolinero( mlr
) para limpiar el espacio en blanco excesivo en la entrada CSV sin encabezado y luego reescribir el tercer campo. El tercer campo se reescribe analizando la fecha dada usando strptime()
la cadena de formato de hora %d-%b-%Y
y luego reformateando la marca de tiempo Unix resultante usando strftime()
la %F
cadena de formato (puede usar, por ejemplo, %Y-%m-%d
en lugar de %F
):
mlr --csv -N \
clean-whitespace then \
put '$3 = strftime(strptime($3,"%d-%b-%Y"),"%F")' file
Dados los datos de la pregunta, esto generaría
1232,abdc,2014-01-02
4534,kdafh,2014-02-20
364,asjhdk,2012-07-11
Si sus datos tienen una marca de tiempo en el mismo campo, puede modificar las cadenas de formato utilizadas en las llamadas strptime()
y strftime()
para adaptarlas a sus necesidades.
Consulte el manual de strftime
su sistema para ver qué significan estas cadenas de formato y cuáles son sus opciones para formatear fechas y horas.
Respuesta3
Suponiendo que ingrese texto es así:
1232,abdc, 02-Jan-2014 18:01:37</br>
4534,kdafh, 20-Feb-2014 07:17:19</br>
364,asjhdk, 11-Jul-2012 23:20:30</br>
mi respuesta sería:
cat input-file.txt | sed 's[</br>[[g' | awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d \""$3" "$4"\" +\"%Y-%m-%d %H:%M:%S\"");}' > output-file.txt
Y si los registros están en una sola línea (no hay una nueva línea en el archivo de entrada después de </br>, sería
cat input-file.txt | sed 's[</br>[\n[g' | awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d \""$3" "$4"\" +\"%Y-%m-%d %H:%M:%S\"");}' > output-file.txt
Respuesta4
No desea bifurcar un nuevo proceso que ejecute un shell y otro comando para cada línea de un archivo, eso sería muy ineficiente. Tener un shell que interprete el código en función de la entrada también es una receta para introducir vulnerabilidades de inyección de comandos. Además, esa -d
opción no es estándar.
Aquí, usaría una herramienta de procesamiento de texto que puede manipular el tiempo, como Perl:
perl -MTime::Piece -pe '
s{\d+-\w+-\d+$}{Time::Piece->strptime($&, "%d-%b-%Y")->ymd}e
' < your-file
Allí, hacemos coincidir lo <digits>-<word-characters>-<digits>
que se encuentra al final de la línea ( $
), lo interpretamos <day>-<month-abbrev>-<year>
y lo reformateamos como si <yead>-<month>-<day>
se usara el módulo principal Time::Pieza de Perl.