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

Respuesta
1

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:

  1. 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.
  2. 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.
  3. 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.

  1. Si justamente lo mencionado lo que necesito es que se busquen los archivos .pdf o .xls en ambas ubicaciones.
  2. 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.
  3.  "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

¡Gracias! 

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.

  1. ¿Qué debe hacerse si existe el archivo BAK pero no es de la fecha de hoy?
  2. ¿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.
  3. ¿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"

Perdón, sobre la coma después del 7, sería

set nombre=%~n1&set nombre=%nombre:~7%

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

¡Gracias! 

De nada

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)

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas