Soy bastante nuevo en BASH scripting y estoy buscando una forma elegante de resolver mi tarea:
En un directorio determinado, ciertos archivos deben clasificarse regularmente en subcarpetas. El nombre de los archivos tiene una estructura fija y la carpeta de destino en la que se colocarán esos archivos, depende de sus nombres.
En este momento mis guiones se ven así:
#!/bin/bash
declare -r SOURCEDIR=/some/dir/upload
declare -r DESTBASEDIR=/some/dir/archive
for year in "2009" "2010" "2011" "2012" "2013" "2014"; do
for letter in {0..9} {A..Z}; do
mkdir -p ${DESTBASEDIR}/${year}/${letter}
mv ${SOURCEDIR}/123456789012_${letter}?_??_${year}????.dat ${DESTBASEDIR}/${year}/${letter}/
done
done
El script hace exactamente lo que quiero, pero crea carpetas de destino incluso si mv no encuentra ningún archivo para moverlo allí. Me gustaría un mv con una opción para crear los directorios necesarios en lugar de crearlos usando mkdir.
Sé que este script mostrará errores cuando no exista ningún archivo para mover. Suprimiré los mensajes de error, cuando se complete el script.
¿Existe una manera fácil y elegante de crear la estructura de directorios sobre la marcha sin crear directores enpty?
¡Gracias por tu ayuda!
Saludos
Manuel
La versión de glenn jackman me inspiró a los siguientes guiones que hacen el truco :)
#!/bin/bash
declare -r SOURCEDIR=/some/dir/upload
declare -r DESTBASEDIR=/some/dir/archive
cd "$SOURCEDIR"
for f in 1234567890_* ; do
letter=${f:11:1}
year=${f:21:4}
dest="$DESTBASEDIR/$year/$letter"
mkdir -p "$dest"
mv "$f" "$dest"
done
Tenga en cuenta que las compensaciones dentro del nombre de archivo se han movido desde que descubrí que el número inicial al principio del nombre de archivo es más corto. La solución dada fue diseñada en mi ejemplo falso.
Este enfoque es menos seguro, ya que no se comprueba si los nombres de archivo de los archivos en el directorio de origen están compuestos como se supone. En este caso, puedo confiar en eso, así que no me arriesgo mucho al no verificar esto.
La línea dada en la versión de glenn jackman.
for f in 123456789012_[A-Z]?_??_[0-9][0-9][0-9][0-9]????.dat ; do
no funciono El valor después de "in" se ha interpretado como una cadena literal en mi bash. No sé cómo "reparar" esto.