8 votos

¿Cómo sustituir una carpeta cuyo nombre es una fecha, es decir, AAAAMMDD, por una jerarquía de carpetas con año, mes y fecha?

Tengo una lista de carpetas que tienen fechas para los nombres. Las fechas tienen el formato AAAAMMDD (por ejemplo, 20150129). Dentro de estas carpetas hay documentos de texto que están relacionados con esa fecha específica.

Me gustaría reestructurarlas en una jerarquía de carpetas que vaya del año al mes y a la fecha, y trasladar los documentos de texto a la carpeta "fecha" correspondiente, situada más abajo en la jerarquía.

En otras palabras, me gustaría que la carpeta 'Root' tuviera el nombre del año como 2015, y luego crear subcarpetas con nombres de meses como 01, y luego crear otras subcarpetas con nombres de fechas como 29 que contengan los documentos de texto correspondientes.

Así que la ruta quedaría como 2015/01/29/file.txt o 2015>01>29>file.txt .

He echado un vistazo a Automator y parece que algo así no es posible aunque puedo estar equivocado, así que me gustaría saber...

  1. ¿Existe alguna solución fácil para este problema que cualquier profano pueda entender, por ejemplo un flujo de trabajo de Automator, o requiere algún conocimiento de comandos de terminal y expresiones regulares?

  2. ¿Cómo se resolvería este problema, si es que existe una solución?

0 votos

A quien haya votado por cerrar esta pregunta como "demasiado amplia", ¿por qué? Tengo curiosidad por saber qué es "demasiado amplio" en esta pregunta.

0 votos

¿Estas carpetas YYYYMMDD están todas directamente dentro de una carpeta maestra o están repartidas en una jerarquía más amplia?

0 votos

@patrix En mi caso están todos en el mismo directorio o carpeta maestra

8voto

siva Puntos 23

Puede utilizar lo siguiente en Terminal. cd a la carpeta que lo contiene, y luego ejecute lo siguiente:

find . -type f -exec bash -c \
  'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})#\1/\2/\3#" <<< $1);\
  mkdir -p -- $(dirname "$F");\
  mv -- "$1" "$F"' - {} \;

find . -type f obtiene todos los archivos del directorio actual de forma recursiva.
-exec bash -c abre un shell para ejecutar los siguientes comandos.
F=$(…) abre un subshell y utiliza sed en la ruta del archivo para manipular la ruta en las carpetas.
^\./([0-9]{4})([0-9]{2})([0-9]{2}) es una regex con tres grupos de captura, como sigue:
\1/\2/\3 es la sustitución, donde cada grupo de captura ( \1 etc.) están separados por / .
mkdir -p -- $(dirname "$F") crea los directorios a los que mover los archivos.
mv -- "$1" "$F" mueve cada archivo a su carpeta correspondiente.

Esto toma la jerarquía de la izquierda y la convierte en la jerarquía de la derecha:

 20170201                2017
    abcdefghij              02
 20170302                       01
     abcdefghij 2                   abcdefghij
                                03
                                    02
                                        abcdefghij 2

Si hay otros archivos en la carpeta contenedora con una fecha como nombre, se moverán como si fueran una carpeta. Para evitarlo, sustituya la segunda línea por:

  'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})(?:/.+)#\1/\2/\3#" <<< $1);\

El (?:/.+) asegura que la ruta tiene un componente posterior, por lo que ignora todo lo que no tenga un hijo en el directorio padre que sean archivos.

0 votos

@klanomath regex101.com

0 votos

@grgarside Gracias

8voto

Suponiendo que todas estas carpetas YYYYMMDD forman parte del mismo directorio principal, podría ejecutar

cd PARENT_DIRECTORY
for d in */; do
    [[ $d =~ [0-9]{8}/ ]] || continue
    mkdir -p -- "${d:0:4}/${d:4:2}"
    mv -- "$d" "${d:0:4}/${d:4:2}/${d:6:2}"
done
  • El for d in */; do lee todas las entradas del directorio, el / garantiza que sólo los nombres de los directorios coincidan realmente
  • [[ $d =~ [0-9]{8}/ ]] comprueba si la entrada actual consta de 8 dígitos, y continúa con la siguiente entrada en caso contrario
  • ${d:0:4}/${d:4:2}/${d:6:2} utiliza la expansión de parámetros dentro de bash para crear una cadena que contenga la nueva ruta
  • El -- en ambos mkdir y mv evita el problema en caso de que el nombre del directorio o del archivo comience con un - . Esto no puede ocurrir aquí, pero probablemente sea una buena práctica de todos modos.

Gracias a @terdon y a @user3439894 por sus ideas para mejorar el script.

0 votos

Gracias por la respuesta, ¡esto funciona perfectamente! Creo que esta solución es mejor que la proporcionada por @grgarside porque es mucho más rápida, especialmente cuando se trata de un corpus masivo que incluye miles de documentos de texto.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X