Optimizar copia de archivos .bat
Dispongo de este código para buscar y copiar archivos que se encuentran en una lista.txt, este código me ayuda a buscar archivos .pdf
@echo off for /f "tokens=*" %%x in ('type Origen.txt') do (echo %%x.pdf) >> Origen2.txt type "Origen2.txt" FOR /F %%i IN (Origen2.txt) DO ( @echo %%i IF exist C:\Users\Windows 7\Desktop\MLFF NUEVO\pdf_reenvio\%%i (echo c:\%%i existe xcopy /s /i "C:\Users\Windows 7\Desktop\MLFF NUEVO\pdf_reenvio"\%%i "C:\Users\Windows 7\Desktop\Buscar_facturas") ELSE (echo no existe) ) rem facturas antiguas FOR /F %%i IN (Origen2.txt) DO ( @echo %%i IF exist "C:\Users\Windows 7\Desktop\antiguas\MLFF Fact-Elec\pdf_reenvio"\%%i (echo c:\%%i existe xcopy /s /i "C:\Users\Windows 7\Desktop\antiguas\MLFF Fact-Elec\pdf_reenvio"\%%i "C:\Users\Windows 7\Desktop\Buscar_facturas") ELSE (echo no existe) ) del type Origen2.txt PAUSE
Su gentil ayuda para optimizar este código, para que realice la búsqueda en ambas rutas, pero además de buscar archivos .pdf también busque archivos .xls
1 respuesta
Me pillas en un momento un poco apurado porque mañana vuelvo de las vacaciones, lo que supone un viaje un poco largo y poca disponibilidad de tiempo, y hoy tampoco puedo dedicar mucho tiempo a esto que planteas. De todas formas voy a ver si entiendo lo que quieres hacer:
- Tienes un archivo ORIGEN.TXT con los nombres, sin extensión, de unos PDF que pueden encontrarse o no en dos ubicaciones. Si se encuentran en alguna de ellas se hace una copia a una misma carpeta.
- Quieres hacer algo parecido con archivos XLS, pero no sé si también sus nombres están en el mismo archivo, ORIGEN.TXT, en cuyo caso habría que revisar si con ese nombre y extensiones PDF o XLS existen archivos en alguna de las dos ubicaciones y si fuera así se haría una copia.
- No entiendo bien el "del type Origen2.txt". Intuyo que quieres borrar los archivos que has copiado, pero así no lo conseguirás.
Aclárame estos puntos para poder seguir cuando ya esté en casa.
- Si justamente lo mencionado lo que necesito es que se busquen los archivos .pdf o .xls en ambas ubicaciones.
- Si correcto, si el archivo existe sea .pdf o .xls se copie en la carpeta correspondiente, si posible que si el archivo ya existe en la carpeta de destino, se omita una nueva copia.
- "del type Origen2.txt" en la parte superior del código estaba agregando manualmente la extensión de los archivos en un archivo llamado "Origen2.txt" que se genera a partir del archivo "Origen.txt"
Si te he entendido bien este BAT podría servirte:
@echo off for /f "tokens=*" %%i in ('type Origen.txt') do ( @echo %%i IF exist "C:\Users\Windows 7\Desktop\MLFF NUEVO\pdf_reenvio\%%i.pdf" (echo %%i.pdf nuevo existe xcopy /s /i "C:\Users\Windows 7\Desktop\MLFF NUEVO\pdf_reenvio\%%i.pdf" "C:\Users\Windows 7\Desktop\Buscar_facturas" ) ELSE (echo %%i.pdf nuevo no existe) IF exist "C:\Users\Windows 7\Desktop\MLFF NUEVO\pdf_reenvio\%%i.xls" (echo %%i.xls nuevo existe xcopy /s /i "C:\Users\Windows 7\Desktop\MLFF NUEVO\pdf_reenvio\%%i.xls" "C:\Users\Windows 7\Desktop\Buscar_facturas" ) ELSE (echo %%i.xls nuevo no existe) rem facturas antiguas IF exist "C:\Users\Windows 7\Desktop\antiguas\MLFF Fact-Elec\pdf_reenvio\%%i.pdf" (echo %%i.pdf antiguo existe xcopy /s /i "C:\Users\Windows 7\Desktop\antiguas\MLFF Fact-Elec\pdf_reenvio\%%i.pdf" "C:\Users\Windows 7\Desktop\Buscar_facturas" ) ELSE (echo %%i.pdf antiguo no existe) IF exist "C:\Users\Windows 7\Desktop\antiguas\MLFF Fact-Elec\pdf_reenvio\%%i.xls" (echo %%i.xls antiguo existe xcopy /s /i "C:\Users\Windows 7\Desktop\antiguas\MLFF Fact-Elec\pdf_reenvio\%%i.xls" "C:\Users\Windows 7\Desktop\Buscar_facturas" ) ELSE (echo %%i.xls antiguo no existe) ) PAUSE
Saludos,
Olvide consultar, como puedo realizar algo similar, leer una lista de nombres de archivos desde una lista.txt, pero con archivos *.bak de la fecha actual y si el archivo no existe, ejecutar un .bat que cree este archivo.
En el archivo lista.txt está listado:
backup_nombre1.bak backup_nombre2.bak backup_nombre3.bak
por ejemplo si en el directorio c:/respaldos, el archivo de la fecha de 23 de agosto del 2022 que se llama ''backup_nombre1.bak", no existe se imprima el mensaje "El archivo no existe" y se ejecute un .bat que creara dicho archivo
De antemano gracias
Si se trata de un problema distinto lo razonable es abrir otra consulta. De todas formas hay algunos puntos que creo que necesitan aclaración.
- ¿Qué debe hacerse si existe el archivo BAK pero no es de la fecha de hoy?
- ¿Cómo se crea el archivo BAK correspondiente cuando no existe? Supongo que copiando el archivo desde alguna otra carpeta, pero eso debería estar claro.
- ¿No sería mejor crear el BAK ausente desde el propio BAT de comprobación en lugar de llamar a otro BAT?
Hola, no me permite crear como nueva pregunta, una disculpa
Desde una lista.txt leer los nombres delos archivos *.bak y mostrar un mensaje por ejemplo de si existe "backup_1.bak de la fecha: DDD/MM/AAAA (fecha actual), archivo existe" caso contrario muestre el mensaje "backup_1.bak de la fecha: DDD/MM/AAAA, no existe"
Si existes otros archivos de fechas anteriores a la actual, se deben ignorar y mostrar el mensaje de "archivo no existe"
Si no existe el archivo de la fecha actual se procede con la copia desde la carpeta correspondiente
El último punto de sí se puede ejecutar un .bat desde otro .bat, es por aclarar si es posible hacerlo.
Saludos
Es un poco raro lo que dices de que no te permite crear una nueva pregunta (no establecer una ya creada "como nueva pregunta") pero bueno.
Prueba con esto:
@echo off Setlocal EnableDelayedExpansion for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do set hoy=%%x&set hoy=!hoy:~0,8!&goto :seguir :seguir set carpresp=c:\respaldos set carporig=c:\origen set listarch=lista.txt for /f "tokens=* usebackq" %%x in ("%listarch%") do ( for /f "tokens=*" %%a in ('dir /b "%carpresp%\%%x"') do ( if "%%a"=="" call :creabak "%%a" if not "%%a"=="" (set fecha=%%~ta&set fecha=!fecha:~6,4!!fecha:~3,2!!fecha:~0,2!) if not !fecha!==!hoy! echo fecha archivo: !fecha! fecha actual: !hoy!&call :creabak "%%a" ) ) pause goto :eof :creabak echo No existe el archivo %carpresp%\%~1 o es antiguo echo copy "%carporig%\%~1" "%carpresp%\%~n1.bak" goto :eof
Asigna a las variables CARPRESP y CARPORIG los valores que le correspondan. Asumo que el archivo LISTA.TXT está en la carpeta actual (en la que se haya guardado el BAT). Como suelo hacer, de momento no se crean los BAK que corresponda crear sino que se hace ECHO de los comandos que se crearían. Si la cosa va como se espera le quitas el ECHO.
Creía que había añadido otra respuesta, porque después de lo anterior comprobé que no me funcionaba correctamente con archivos BAK, además de otro errorcillo en el COPY final. En pruebas posteriores resultó que, tal como está, solo funciona con TXT. No he conseguido encontrar la razón pero esto me llevó a abordar de forma ligeramente distinta la solución. Esta es la que creo válida:
@echo off Setlocal EnableDelayedExpansion for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do set hoy=%%x&set hoy=!hoy:~0,8!&goto :seguir :seguir set carpresp=c:\respaldos set carporig=c:\origen set listarch=lista.txt for /f "tokens=* usebackq" %%x in ("%listarch%") do call :tratar "%%x" pause goto :eof :tratar for /f "skip=5 tokens=1,4" %%a in ('dir "%carpresp%\%~1"') do ( if "%%a"=="No" call :creabak "%~1"&goto :eof if not "%%a"=="No" (set fecha=%%a&set fecha=!fecha:~6,4!!fecha:~3,2!!fecha:~0,2! if not !fecha!==!hoy! (echo fecha archivo: !fecha! fecha actual: !hoy!&call :creabak "%%b"&goto:eof ) else goto:eof ) ) goto :eof :creabak echo No existe el archivo %carpresp%\%~1 o es antiguo copy "%carporig%\%~n1.*" "%carpresp%\%~n1.bak">nul goto :eof
Asumo que las variables CARPRESP y CARPORIG apuntan a la carpeta donde deben estar los respaldos con fecha de hoy y que el archivo LISTA.TXT se encuentra en la misma carpeta que este BAT una vez salvado. También que si hay que crear un BAK para alguno de los archivos su nombre será el que figura en LISTA.TXT aunque con otra extensión.
Ya nos dirás si va bien.
Por cierto que para llamar a un bat desde dentro de un bat hay que usar el comando CALL.
Y si la estructura de los registros de LISTA.TXT es backup_<nombreArchivo>. Bak habría que añadir una línea de código para extraer el nombre del archivo y cambiar el comando COPY adecuadamente. Algo como:
set nombre=%~n1&set nombre=%nombre:~7,% copy "%carporig%\%nombre%.* "%carpresp%\backup_%nombre%.bak"
Espero que esta ya sea la buena. Resulta que he visto más fallos en el bat propuesto y he decidido probarlo un poco más a fondo. Así es como me ha quedado:
@echo off Setlocal EnableDelayedExpansion for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do set hoy=%%x&set hoy=!hoy:~0,8!&goto :seguir :seguir set carpresp=c:\respaldos set carporig=c:\origen set listarch=lista.txt for /f "tokens=* usebackq" %%x in ("%listarch%") do call :tratar "%%x" pause goto :eof :tratar dir "%carpresp%\%~1">nul 2>&1||call :creabak "%~1" for /f "skip=5 tokens=1,4" %%a in ('dir "%carpresp%\%~1"') do ( if "%%a"=="No" call :creabak "%~1"&goto :eof if not "%%a"=="No" (set fecha=%%a&set fecha=!fecha:~6,4!!fecha:~3,2!!fecha:~0,2! if not !fecha!==!hoy! (echo fecha archivo: !fecha! fecha actual: !hoy!&call :creabak "%%b"&goto:eof ) else goto:eof ) ) goto :eof :creabak echo No existe el archivo %carpresp%\%~1 o es antiguo set nombre=%~n1 set nombre=%nombre:~7% copy "%carporig%\%nombre%.*" "%carpresp%\backup_%nombre%.bak" goto :eof
A ver si hay suerte
Saludos,
funciona muy bien, sin embargo, tengo varias dudas:
- Si en la lista.txt, no se encuentra todo el nombre del archivo, que hay que agregar para que igual haga la búsqueda?, por ejemplo los respaldos se generan con el nombre "backup_fecha_actual", pero en la lista.txt solo se agrega el nombre "backup"
- Que cambiar para que las fechas de comparación se muestren en formato "diamesaño" por ejemplo: fecha archivo: 30082022 fecha actual: 30082022
-Si el archivo ya existe que se muestre el mensaje: "El archivo ya existe"
No entiendo bien tu primera pregunta. Intuyo que quieres decir que en LISTA.TXT solo figure el nombre del archivo, no el nombre del BAK asociado. Por ejemplo:
JAIME Resultados TORMENTA
y, sin embargo, se busquen en la carpeta de respaldos:
BACKUP_JAIME.BAK BACKUP_RESULTADOS.BAK BACKUP_TORMENTA. BAK
Pero, en el supuesto de que esto fuera así, no entiendo cuando dices:
Los respaldos se generan con el nombre "backup_fecha_actual", pero en la lista.txt solo se agrega el nombre "backup"
El bat actual genera, si es necesario, respaldos con el nombre "backup_<nombreArchivo>.bak" no con el nombre "backup_<fechaActual>" pero no toca el archivo LISTA.TXT.
Para atender la segunda petición habría que cambiar las líneas:
for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do set hoy=%%x&set hoy=!hoy:~0,8!&goto :seguir if not "%%a"=="No" (set fecha=%%a&set fecha=!fecha:~6,4!!fecha:~3,2!!fecha:~0,2!
por estas otras:
for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do set hoy=%%x&set hoy=!hoy:~6,2!!hoy:~4,2!!hoy:~0,4!&goto :seguir if not "%%a"=="No" (set fecha=%%a&set fecha=!fecha:~0,2!!fecha:~3,2!!fecha:~6,4!
Como, de alguna manera, ya se está informando de los casos en los que el archivo existe aunque el respaldo sea antiguo (mensajes tipo "fecha archivo: 20220825 fecha actual: 20220830") entiendo que quieres que se informe también de los casos en que el respaldo existe y es de hoy. Creo que cambiando las líneas:
if not !fecha!==!hoy! (echo fecha archivo: !fecha! fecha actual: !hoy!&call :creabak "%%b"&goto:eof ) else goto:eof
por estas otras:
if not !fecha!==!hoy! (echo Archivo %%b existe con fecha archivo: !fecha! fecha actual: !hoy!&call :creabak "%%b"&goto:eof ) else (echo Archivo %%b existe con respaldo correcto&goto:eof)
- Compartir respuesta