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 relacionados con esa fecha específica.
Me gustaría reestructurarlos en una jerarquía de carpetas que vaya de un año a otro hasta la fecha, y mover los documentos de texto a la carpeta de 'fecha' correspondiente más abajo en la jerarquía.
En otras palabras, me gustaría que la carpeta 'raíz' tenga el nombre de un año como 2015, y luego cree subcarpetas con nombres de meses como 01, y luego cree subcarpetas adicionales con nombres de fechas como 29 que contengan los documentos de texto correspondientes. .
Entonces el camino se verí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 podría estar equivocado, así que me gustaría saber…
¿Existe alguna solución fácil para este problema que cualquier profano pueda entender, por ejemplo, un flujo de trabajo de Automator, o esto requiere cierta comprensión de los comandos del terminal y las expresiones regulares?
¿Cómo se resolvería este problema si de hecho hay una solución?
Suponiendo que todas estas carpetas AAAAMMDD sean parte del mismo directorio principal que 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
for d in */; do
ciclo lee todas las entradas del directorio, el rastreo /
asegura que solo los nombres de los directorios realmente coincidan[[ $d =~ [0-9]{8}/ ]]
comprueba si la entrada actual consta de 8 dígitos y continúa con la siguiente entrada si no${d:0:4}/${d:4:2}/${d:6:2}
usa la expansión de parámetros dentro bash
para crear una cadena que contiene la nueva ruta--
en ambos mkdir
y mv
evita problemas en caso de que el directorio o el nombre del archivo comience con una extensión -
. Esto no puede suceder aquí, pero probablemente sea una buena práctica de todos modos.Gracias a @terdon y @user3439894 por sus ideas sobre cómo mejorar el guión original.
Puede usar lo siguiente en Terminal. cd
a la carpeta que lo contiene, 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 en el directorio actual recursivamente.
-exec bash -c
abre un shell para ejecutar los siguientes comandos.
F=$(…)
abre una subcapa y usa sed en la ruta del archivo para manipular la ruta a las carpetas.
^\./([0-9]{4})([0-9]{2})([0-9]{2})
es una expresión regular con tres grupos de captura, de la siguiente manera: es reemplazo, donde cada grupo de captura ( , etc.) está separado por . crea los directorios para mover los archivos. mueve cada archivo a su carpeta correspondiente.
\1/\2/\3
\1
/
mkdir -p -- $(dirname "$F")
mv -- "$1" "$F"
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 evitar esto, reemplace la segunda línea con:
'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})(?:/.+)#\1/\2/\3#" <<< $1);\
El (?:/.+)
garantiza que la ruta tenga un componente subsiguiente, por lo tanto, ignora todo lo que no tenga un elemento secundario en el directorio principal, que son archivos.
usuario3439894
sin ladera
davidjnatarajan