Bash: convierte todas las instancias del formato de fecha dd-mm-aaaa a aaaa-mm-dd [cerrado]


-3

Sí, antes de que alguien salte y me ataque con una horca, esta es una pregunta duplicada, pero las otras no funcionan para mí, así que ahora me lo pregunto.

Tengo un archivo CSV que tiene fechas en algún lugar de cada entrada. La dificultad añadida a la conversión es que a veces las fechas tendrán un solo dígito por días. Entradas de ejemplo:

abc,0,2,-2,3-16-1994
xyz,1,2,3,10-09-1994

Quiero algo, preferiblemente sed, para convertir esas entradas de datos para que se vean así:

abc,0,2,-2,1994-03-16
xyz,1,2,3,1994-09-10

He intentado:

sed 's|(..)-(..)-(....)|\3-\2-\1|'

Pero eso da un error y realmente no cubre los problemas del día de un solo dígito.

También probé:

awk -F - '{print $3$2$1}'

Esto en realidad tiene un efecto deseado, pero de nuevo, no realmente. El comando awk lo convierte, pero solo el mes y el año, y en lugar de volver a poner la fecha donde estaba, pone el mes y el año del comienzo de la línea, dejando la parte del día donde estaba originalmente.

¡Cualquier ayuda sería increíble!

Gracias por adelantado.

Editar

Se señaló acertadamente en los comentarios que cometí un error con mis ejemplos. Las fechas deben ser:

abc,0,2,-2,16-03-1994
xyz,1,2,3,2-05-1994

Con el resultado deseado siendo:

abc,0,2,-2,1994-03-16
xyz,1,2,3,1994-05-02

Lo siento chicos.


¿Puedes explicar qué pasa con las otras soluciones que no funcionaron? ¿No son el formato final que desea o no son apropiados para la entrada con la que está tratando u otra cosa?
music2myear

@ music2myear Le expliqué qué salió mal con la solución awk. El comando sed en realidad arrojó un error, quejándose de que faltaba algo en "RE", un error que nunca había visto antes.
user1840352

¿Has mirado más en ese error?
music2myear

Como John C señala en su respuesta , usted dice que sus datos son '' dd-mm-aaaa '', pero sus datos de ejemplo incluyen '' 3-16-1994 '', que significa el tercer día del mes 16, así que tu pregunta es defectuosa
Scott

@ Scott solucioné mi pregunta con una edición en la parte inferior. Perdón por el error engañoso.
user1840352

Respuestas:


1

sed -r 's/(\d{1,2})-([0-9]{2})-([0-9]{4})/\3-\2-\1/g' parece hacer el truco, puede haber otras formas "más inteligentes" ... No sé

mi código:

x="abc,0,2,-2,3-16-1994#xyz,1,2,3,10-09-1994"
echo $x |tr '#' '\n'| sed -r 's/([0-9]{1,2})-([0-9]{2})-([0-9]{4})/\3-\2-\1/g'

produce:

abc,0,2,-2,1994-16-3
xyz,1,2,3,1994-09-10

2 "advertencias" para sus datos ... es un poco inconsistente (tal vez fue solo por el bien del ejemplo) ...

  • en la primera línea, el primer elemento de la fecha no está "rellenado con ceros"
  • después de mirar la segunda línea, no está claro si los datos de entrada son dd-mm-yyyyomm-dd-yyyy

Edición posterior: Primero me perdí la parte de que el relleno del día era un requisito, teniendo esto en cuenta, parece que lo siguiente ayuda

echo $x |tr '#' '\n'| sed -r 's/\b([0-9])-([0-9]{2})-([0-9]{4})\b/\3-\2-0\1/g; s/\b([0-9]{2})-([0-9]{2})-([0-9]{4})\b/\3-\2-\1/g'

prácticamente tenemos 2 expresiones regulares, una (la primera) coincide con las "fechas" donde el día tiene solo 1 dígito y agrega el relleno "0" al hacer la sustitución, la otra coincide con las "fechas" que tienen el día con 2 dígitos y solo el reordenamiento de los elementos

Tengo la idea de aquí https://stackoverflow.com/questions/12129382/add-leading-0-in-sed-substitution , así que felicitaciones a la persona que respondió allí


Por un lado, sí, la pregunta es errónea. Por otro lado, la pregunta dice, "a veces las fechas tendrán un solo dígito por días", y muestra el ejemplo de que 3en la entrada se convierte 03en la salida.
Scott

era (muy) tarde en mi zona horaria y me perdí esa parte del "requisito", actualicé la respuesta para cubrirlo
Lohmar ASHAR

Parece funcionar. Si agrega s/\b([0-9]{1,2}-)([1-9]-[0-9]{4})\b/\10\2/;al comienzo de la sedcadena de comando, también manejará meses de un solo dígito.
Scott

@LohmarASHAR Gracias, probé tu solución. Primero el "--r" me da un problema de argumento ilegal. Al eliminar eso, aparece este error "sed: 1:" s / \ b ([0-9]) - ([0-9] {2}) - ... ": \ 3 no definido en el RE"
user1840352

solo hay 1 guión ("-") antes de la "r" ... o tal vez es solo un error tipográfico en su comentario, de todos modos estoy usando bash WSL (ubuntu en windows), sed --versiondice sed (GNU sed) 4.2.2, sed --helpda -r, --regexp-extended use extended regular expressions in the script.. En otros servidores (algunos debian y centos) encontré la versión 4.2.1, y todavía funciona así que ... tal vez no fue un error tipográfico en el comentario
Lohmar ASHAR

0

Esto funciona cuando lo pruebo, tenga en cuenta que he cambiado día y mes ya que el formato original en su ejemplo es en realidad mm-dd-aaaa. No estoy seguro de si el relleno cero es importante para usted o no, no lo he intentado:

sed -i -r 's|([[:digit:]]*)-([[:digit:]]*)-([[:digit:]]*)|\3-\1-\2|' test.csv
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.