Modificar .bat para que solo copie archivos con extensiones especificas.

Tengo un problema con un código ya que no se como hacer para que me copie las extensiones de archivos que deseo y no todos los archivos.

Se modificarlo para que por ejemplo me copie solo una extensión específica, pero si le añado una coma y pongo más extensiones me dice que el numero de parámetros no son válidos.

A continuación dejo el código,

@echo off

:USB

echo Esperando usb...

for %%u in (a, b, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) do (
dir /b %%u:\ > nul 2>&1 && (
for /f "tokens=8*" %%a in ('vol %%u: ^| find "volumen de la unidad"') do (echo Unidad %%u:\ "%%a" detectada

if exist "%c:%\archivos\%%u-%%a" (goto USB) else (xcopy /s /c /i "%%u:"\*.* %c:%\archivos\"%%u-%%a" & goto USB)

)
)

)

goto USB

exit

1

1 Respuesta

87.425 pts. Experiencia en manejo de bases de datos Oracle,...

Efectivamente el comando xcopy no permite "selección múltiple" de tipos de archivo a copiar (o no he sabido encontrarla). De modo que creo que no queda más remedio que repetir el comando xcopy para cada uno de los tipos que se desee copiar. Algo así:

@echo off
:USB
Echo Esperando usb...
for %%u in (a, b, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) do (
dir /b %%u:\ > nul 2>&1 && (
for /f "tokens=8*" %%a in ('vol %%u: ^| find "volumen de la unidad"') do (echo Unidad %%u:\ "%%a" detectada
if exist "%c:%\archivos\%%u-%%a" (goto USB) else (
xcopy /s /c /i "%%u:"\*.doc %c:%\archivos\"%%u-%%a"
xcopy /s /c /i "%%u:"\*.xls %c:%\archivos\"%%u-%%a"
xcopy /s /c /i "%%u:"\*.pdf %c:%\archivos\"%%u-%%a"
goto USB
)
)
)
)
goto USB
exit

Aunque me permito sugerirte esta otra opción, creo que un poco optimizada:

@echo off
:USB
echo Esperando usb...
for %%u in (a, b, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) do (
dir /b %%u:\ > nul 2>&1 && (
for /f "tokens=8*" %%a in ('vol %%u: ^| find "volumen de la unidad"') do (echo Unidad %%u:\ "%%a" detectada
if not exist "%c:%\archivos\%%u-%%a" (
xcopy /s /c /i "%%u:"\*.doc %c:%\archivos\"%%u-%%a"
xcopy /s /c /i "%%u:"\*.xls %c:%\archivos\"%%u-%%a"
xcopy /s /c /i "%%u:"\*.pdf %c:%\archivos\"%%u-%%a"
)
)
)
)
goto USB
exit

Muchísimas gracias! Has sido de gran ayuda. 

Un saludo! 

Hola de nuevo. 

Acudo otra vez a tu sabiduría, 

Me surge otro problema con el código. Cuando introduzco una memoria que no tiene nombre, directamente se crea una carpeta con el nombre de la unidad más la palabra tiene, (algo asi 'e-tiene' ) 

Me gustaría indicar en el código, si es posible, que cada vez que se introduzca una memoria sin nombre, la carpeta que se cree tenga un nombre distinto, ya que sino si se crea la carpera e-tiene, no producirá a realizar la copia de las tablas excel que necesito diariamente de las memorias que se introduzcan en el pc, y tengo que ir manualmente a copiarlas una a una. 

Muchas gracias de antemano por toda tu ayuda. 

Un saludo. 

Si no tiene mucha importancia el reconocer las unidades que tienen nombre, lo más sencillo sería utilizar como identificador el número de serie del dispositivo insertado, en vez del nombre de la unidad, para lo cual bastaría con cambiar la cadena buscada con el find.

En lugar de:

for /f "tokens=8*" %%a in ('vol %%u: ^| find "volumen de la unidad"') do (echo Unidad %%u:\ "%%a" detectada

se utilizaría:

for /f "tokens=8*" %%a in ('vol %%u: ^| find "serie del volumen"') do (echo Detectada unidad %%u:\ con serie "%%a"

Da la casualidad de que el número de serie también ocupa la 8ª posición en su línea. El uso del número de serie resuelve el problema de asignar un nombre único para cada dispositivo.

Si prefieres seguir usando el nombre de la unidad, cuando lo tenga, y el número de serie en caso contrario, puedes probar este otro bat. Se basa en el tuyo pero he quitado algunas cosas que me chocaban (como %c:% que no sé que puede ser pero supongo que te funciona aunque probablemente es una cadena vacía):

@echo off
Setlocal EnableDelayedExpansion
:USB
Echo Esperando usb...
for %%u in (a, b, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) do (
   dir /b %%u:\ > nul 2>&1 && (
      set tratada=N
      for /f "tokens=8*" %%a in ('vol %%u:') do (
         if not "%%a"=="tiene" if "!tratada!"=="N" echo Unidad %%u:\ "%%a" detectada&call :copia %%u "%%a"&set tratada=S
         if "%%a"=="tiene" echo Unidad %%u:\ sin etiqueta
      )
   )
)
goto USB
:copia
cd\
if not exist "\archivos\%1-%~2" (
   xcopy /s /c /i "%1:\*.doc" "\archivos\%1-%~2"
   xcopy /s /c /i "%1:\*.xls" "\archivos\%1-%~2"
   xcopy /s /c /i "%1:\*.pdf" "\archivos\%1-%~2"
   )

Buenas tardes,

Muchas gracias por la solución que me has dado, pero el código sigue dándome problemas.

Estoy usando el ultimo código que me enviaste

@echo off
Setlocal EnableDelayedExpansion
:USB
Echo Esperando usb...
for %%u in (a, b, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) do (
   dir /b %%u:\ > nul 2>&1 && (
      set tratada=N
      for /f "tokens=8*" %%a in ('vol %%u:') do (
         if not "%%a"=="tiene" if "!tratada!"=="N" echo Unidad %%u:\ "%%a" detectada&call :copia %%u "%%a"&set tratada=S
         if "%%a"=="tiene" echo Unidad %%u:\ sin etiqueta
      )
   )
)
goto USB
:copia
cd\
if not exist "\archivos\%1-%~2" (
   xcopy /s /c /i "%1:\*.doc" "\archivos\%1-%~2"
   xcopy /s /c /i "%1:\*.xls" "\archivos\%1-%~2"
   xcopy /s /c /i "%1:\*.pdf" "\archivos\%1-%~2"
   )

Pero el problema que me ocurre ahora, es que una vez copiados todos los excel que necesito de la memoria, en la pantalla de ms-dos, me sigue pidiendo si quiero sobrescribirlo, en vez de como estaba en el código original, que si ya tenia la carpeta con ese nombre, directamente seguía saltando la función USB del código, mientras que ahora me pide en bucle si quiero únicamente sobrescribir y me impide sacar la memoria de forma segura (desconectándolo desde el área de notificación de windows) ni conectar otras memorias para que se pueda producir la copia de nuevas hojas de calculo.

Muchas gracias de nuevo por todo y discúlpame por tanta molestia.

Un saludo

Perdón por el post anterior,  pero lo que me enviaste está perfecto.

Resulta que lo empecé a introducir a mano para ir aprendiendo, ya que mis conocimientos son de tutoriales por internet, y no puse el código tal cual.

Me resuelve el problema al 100%.

Reitero mis más sinceros agradecimientos por tu ayuda, es un placer que haya gente como tu.

Un saludo.

Me alegro mucho. La verdad es que he leído los dos mensajes a la vez y no me ha dado tiempo a preocuparme, pero lo cierto es que al leer el primero me sorprendió porque estuve haciendo bastantes pruebas antes de encontrar esa solución y darla por buena.

Desde que empecé a usar Internet (bueno, antes incluso, cuando había grupos de news) lo que más me gustó era la posibilidad de ayudar sin contrapartida, sin precio y sin coste. Mucha gente me ha ayudado (y me sigue ayudando). Y a mí me encanta poder echar una mano, porque disfruto intentando resolver los problemas que me plantean.

Es un gusto que haya gente que ayude sin pedir nada a cambio.

Me llamó mucho la atención la linea de comando 

EnableDelayedExpansion

Voy a seguir investigando y aprendiendo ya que veo que tu código es muy profesional con mis humildes primeras intenciones para lo que quería hacer.

Mi siguiente objetivo es conseguir desde tu código, que las carpetas ya creadas con el mismo nombre o numero de serie de la memoria, copien las nuevas tablas (el archivo excel) si dentro de la carpeta del pc no están los nuevos archivos que hay en una misma memoria ya previamente creada la carpeta. (claro está que el nuevo archivo excel tenga el misma nombre).

Así no me requerirá diariamente borrar las carpetas para que se puedan volver a copiar.

He estado leyendo, (aunque imagino que ya lo sabrás) que si al poner la extensión .xls le añades una ? (.xls?) copia tanto los archivos xls como los xlsx del nuevo office.

¡Un saludo!

Perdón de nuevo, escribí muy rápido el post y cometí un error al expresarme.

Quería decir que el nuevo archivo excel no tenga el mismo nombre que el que ya hay en la carpeta del pc. (en realidad los excel llevan la fecha del día mas la sección y el programa de la tarea asignada, por lo que nunca coincidirían con los .xls anteriores)

Gracias de nuevo.

La variable de entorno EnableDelayedExpansion habilita lo que los desarrolladores (y traductores) de la shell cmd de Microsoft llaman expansión retardada. Puedes ver lo que cuentan ellos si tecleas SET /? en una ventana CMD.

Concretamente si quieres que dentro de un bucle los cambios en el valor de una variable tengan efecto, debes habilitarla y recuperar el valor de la variable invocándolo entre ! En lugar de entre %%. En nuestro caso la variable TRATADA me sirve para impedir que una unidad tratada por tener nombre vuelva a ser tratada al leer el número de serie. Pero el cambio en el valor de N a S se hace dentro del bucle FOR. Por eso se comprueba su valor con ! Tratada! En lugar de hacerlo con %tratada% habiendo habilitado, previamente, la variable de la que estamos hablando.

En cuanto a usar el comodín "?" para conseguir que te copie tanto los xls como los xlsx creo que, en esta ocasión, no es necesario y que *.xls te permitirá copiar los archivos que incluyan en su nombre ".xls". Puedes comprobarlo si te sitúas en una carpeta que tenga archivos de ambos tipos y tecleas el comando DIR *.XLS

El editor de la página altera algunas cosas, en este caso sin demasiada importancia (como suprimir uno de los dos ! Que había puesto, separar la primera ! Del nombre de la variable "tratada" y ponerle mayúscula a ese nombre). Ya no estoy tan seguro de que haya sido culpa del editor o mía que se diga

... Y que *.xls te permitirá copiar los archivos que incluyan en su nombre ".xls"...

Cuando debía decir

... Y que *.xls te permitirá copiar los archivos que incluyan en su nombre ".xlsx"...

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas