viernes, 19 de noviembre de 2010

Backup de varias carpetas en archivos comprimidos separados

Backup de varias carpetas en archivos comprimidos separados

5b415a0a74765006f122f979f487f751
En otras palabras: script para generar un archivo comprimido por subcarpeta, a partir de una carpeta dada.

Hace un tiempo me encontré con una necesidad puntual. Tengo un directorio principal con varios subdirectorios (o subcarpetas, si les gusta) que necesito respaldar. Para hacer un backup quiero comprimir ese directorio, pero en lugar de tener un solo graaaaaan archivo, prefiero tener un archivo por cada subdirectorio del primer nivel. Sería así: supongamos el directorio "Archivos de la empresa" y los subdirectorios "Gerencia", "Administracion", "RRHH", "Sistemas". Cada subdirectorio puede tener a su vez más subdirectorios y archivos dispersos. Lo que quiero es generar un comprimido por cada subdirectorio principal: Gerencia, Administracion, RRHH y Sistemas.

Para lograr este cometido:
- creé una carpeta para guardar los archivos comprimidos
- prepare un script que se encarga del trabajo sucio
- programé el script como "tarea programada" de windows para que se ejecute aunque yo no me acuerde (se puede ejecutar a mano, obviamente)

Además el script un log (un reporte de como anduvo todo). Esto se puede verificar a diario para constatar el funcionamiento. Es un archivo HTML, traté de que se vea bonito.

Al comprimir toma todos los archivos dentro de la carpeta especificada, sin importar su contenido. Podría filtrarse en la linea del 7zip para que ignore algunas extensiones.
Ah, los archivos los comprimo con 7zip http://www.7zip.com, que es mas eficiente que el winzip y ademas es gratis. Pero se puede usar cualquier compresor que soporte línea de comando (winzip, winrar tambien). (Usa formato 7z en lugar de zip).

El script funciona así:
- primero se define el nombre y ubicacion del archivo de reporte, de la carpeta a comprimir, una ubicacion temporal y el directorio donde queremos dejar los archivos comprimidos.
- luego genera un poco de presentacion para el reporte html
- crea una lista de subdirectorios en el archivo temporal
- luego recorre esa lista generando un archivo comprimido por cada linea del temporal (que corresponde a un subdirectorio)

Dejé el archivo profusamente comentado para que puedan seguirlo línea x línea. En el ejemplo, hará un backup de todas las carpetas contenidas en d:videos, dejando un archivo comprimido por cada carpeta en el directorio d:prueba.
También en ese lugar creará un log (ReporteCompresion.html).
Si quieren que al finalizar el script aparezca el reporte en pantalla, se puede usar la última línea (la dejé comentada, solo hay que borrar el doble dos puntos). Al reporte lo sobreescribe en cada ejecucion.

Atencion. Hay una limitacion: los subdirectorios de primer nivel no pueden tener espacios en sus nombres. El directorio "Gerencia" lo puede comprimir perfecto, pero el directorio "Gerencia general" arrojará error. Solucion: renombrarlo como GerenciaGeneral. Con linux lo solucionaba en dos patadas, pero con windows se me complica...
Agregado: ya encontré como solucionarlo. Corregi el fuente. Ahora soporta nombres de carpeta con espacios....

Este es el fuente. Hay que crear un archivo de texto y darle la extension .bat para usarlo como script.
Deberia funcionar barbaro en 2000 y Vista también, pero lo probé 100% en XP y 2003.

@echo off
rem Primero hay que configurar el script: con estas cuatro lineas
rem REPORT es el archivo HTML que sirve de log
rem RAID es la carpeta que vamos a comprimir (todo su contenido)
rem TEMPORAL es un archivo que genera el script como "borrador". lo borra antes de terminar
rem atencion! hay que tener permisos de escritura en la ubicacion de TEMPORAL
rem DESTINO es la ubicacion de los archivos comprimidos
set REPORT=d:pruebaReporteCompresion.html
SET RAIZ=d:videos
SET TEMPORAL= d:pruebacarpetas.txt
SET DESTINO=d:prueba
rem *****************************************************************************
rem * Jairh, en edicion especial para Taringa! - 20/05/2010 *
rem *****************************************************************************
rem Se ven feas las lineas porque hay que poner un caret (acento circunflejo) antes
rem de cada signo mayor y menor. Seria el equivalente a "escapar" caracteres en C
echo ^^^Reporte de backup^^ >%REPORT%
echo ^^Compresion de backup >>%REPORT%
echo ^
>>%REPORT%
echo ^T! 2010^>>%REPORT%
echo ^
>>%REPORT%
rem Todo lo anterior es para darle formato de html y algun rotulo
rem Ahora pega la fecha y hora del sistema
echo ^Fecha y hora: ^ >>%REPORT%
date /t >>%REPORT%
time /t >>%REPORT%
echo ^
^
>>%REPORT%
echo ^
>>%REPORT%
:: (C) JH
rem *****************************************************************************
rem *
rem * Parámetros de 7zip empleados en la compresión:
rem *
rem *
rem * a Añadir ficheros al archivo
rem *
rem *
rem * -bd No muestra el indicador de progreso (porcentaje)
rem * -r Incluye las subcarpetas
rem *****************************************************************************
rem
rem
rem
echo ^Compresión con algoritmo 7zip parámetros: a -bd -r ^>>%REPORT%
echo ^Detalla de salida del proceso^>>%REPORT%
echo ^>>%REPORT% 

rem La siguiente linea genera un archivo temporal con los subdirectorios a comprimir dir %RAIZ% /b /ad > %TEMPORAL% 
rem Esto es para ubicarse en la carpeta que vamos a comprimir: pushd %RAIZ% echo Generando archivos comprimidos... 
rem Ahora viene la magia. Un FOR en scripts de linea de comando!!!! 
rem Lo que hace el FOR es recorrer el archivo TEMPORAL linea por linea 
rem Cada linea es un directorio, asi que generará un archivo comprimido que contenga ese directorio 
rem Si se desea otro compresor (no 7zip) habria que modificar la ruta (a partir del DO) 
rem y los parametros. 
rem ATENCION!!!! SI COPIAS Y PEGAS, LA SIGUIENTE LINEA POR AHI QUEDA CORTADA rem EMPIEZA CON FOR y termina con REPORT% FOR /f "delims=," %%1 IN (%TEMPORAL%) DO "%programfiles%7-Zip7z.exe" a -bd -r "%DESTINO%backup%%1" "%cd%%%1*.*" >>%REPORT% popd 
echo ^>>%REPORT%
echo ^>>%REPORT% 

echo Limpiando temporales... del %TEMPORAL% 
echo ^>>%REPORT%
echo ^Hora de finalizacion: ^ >>%REPORT%
time /t >>%REPORT%
echo ^
^
>>%REPORT%
echo ^
^
>>%REPORT%
:: start %REPORT%


Lo tengo hiper testeado....

Espero les sea útil. Acepto correcciones, pedidos y sugerencias...

Sobre el FOR, te cuento Santiago:
Es bastante limitado, pero permite hacer varias cosas interesantes. Para empezar, puede recorrer un archivo y ejecutar una acción en cada campo (en el caso de mi script, de cada línea). Permite también recorrer variables de entorno. Sobre la sintaxis que uso:
FOR /f "delims=," %%1 IN (%TEMPORAL%) DO "%programfiles%7-Zip7z.exe" a -bd -r "%DESTINO%backup%%1" "%cd%%%1*.*" >>%REPORT%
No es tan complicado, pero se hace largo con la línea del 7z. Empiezo de atrás para adelante:
>>%REPORT%
Hace que la salida vaya al reporte en html
"%programfiles%7-Zip7z.exe" a -bd -r "%DESTINO%backup%%1" "%cd%%%1*.*"
Ejecuta 7z buscandolo en la carpeta de "Archivos de programa" segun la instalacion local (por eso la variable de entorno).
Los parametros -a -bd -r son de 7z, los comento en el script.
Lo que devuelve el FOR es una variable, en este caso %%1 (doble porcentual por tratarse de un script).
FOR /f "delims=," %%1 IN (%TEMPORAL%) DO
El parametro /F lo uso para recorrer el archivo, aunque se que se puede usar para salidas de otros comandos.
La opcion "delims=," hace que use la coma como separador de línea. El separador de campos por default es tabulador o espacio, al poner la coma (que en mi ejemplo nunca llega) lee toda la línea como un solo campo (entonces elimina el problema del espacio en el nombre de archivo).
Las palabras clave IN y DO son propias de la sintaxis del FOR.
IN determina que lo que sigue es el origen de las variables (en mi caso el archivo temporal)
DO indica que lo que sigue debe ejecutarse para cada ocurrencia del FOR.
Si querés ver qué hace, podés agregar una línea que diga "echo on" justo antes del FOR. Vas a ver por pantalla cómo expande la variable y ejecuta un 7z por cada línea de %temporal%.




ESPERO QUE LES HALLA SERVIDO....

No hay comentarios:

Publicar un comentario