¿Cómo hacer un archivo Bat que modifique nombre y extensión de un lote de archivos?
He visto que gustas de resolver este tipo de problemas y espero me puedas ayudar.
Tengo un lote de 5000 archivos que necesito renombrar (parte del nombre y su extensión):
Ejemplo:
Respuesta000001.cms.txt
Respuesta000002.cms.txt
Archivos1.cms.txt
Archivos2.txt
Lo que necesito, es cambiar el . Cms.txt por .txt.cms.out unicamente de los archivos que inician con el nombre Respuesta.
¿Me podrías tirar un cable?
1 Respuesta
Prueba con esto:
@echo off Setlocal EnableDelayedExpansion cd \CarpOrig for /f %%i in ('dir /b *.txt ^| find "Respuesta"') do ( set arch=%%i set arch=!arch:~0,-7!txt.cms.out echo ren "%%i" "!arch!" )
Se supone que todos los archivos a renombrar están en una carpeta de nombre "CarpOrig" y en la misma unidad en la que está el bat que se va a encargar de hacer el trabajo. Si no fuera así (si no estuviera en la misma unidad) en la tercera instrucción deberías poner el comando o comandos que sitúen en la carpeta en cuestión. Pruébalo y me dices.
Perdón. En la última instrucción debes eliminar el "echo" (así lo tengo en mi bat de prueba para que no me cambie el nombre sino solo me presente el comando que se ejecutaría y poder seguir probando). Por tanto debería quedar:
Ren "%%i" "!arch!"
Primero que nada, gracias por responder.
Cambie el nombre de la carpeta a CarpOrig y la puse en C
El bat igual lo puse en C
Al ejecutarlo no hace ningún cambio en los archivos de la carpeta.
Estoy haciendo algo mal?
Saludos
No sé si mi última corrección la has tenido en cuenta. En todo caso escribe aquí el texto del bat para que pueda ver si hay algún error.
Sí usé tu última corrección.
Aquí el script:
@echo off
Setlocal EnableDelayedExpansion
cd \CarpOrig
for /f %%i in ('dir /b *.txt ^| find "Respuesta"') do (
set arch=%%i
set arch=!arch:~0,-7!txt.cms.out
ren "%%i" "!arch!"
)
y como te decía, ambos (carpeta y bat) se encuentran en C raíz.
Ya sé por donde va más o menos el problema:
Funciona para los archivos con nombre Respuesta000001.cms.txt
Pero no para los archivos RESPUESTA_MXOMASIP-20161206104035260.cms.txt
Ya casi está listo, el problema es que modifica archivos de un nombre casi idéntico que no deseo modificar.
Aquí lo ejemplifico:
Tengo archivos con estos nombres:
RESPUESTA_MXOMASIP-20160915094024349.txt
RESPUESTA_MXOMASIP-20161206104035260.cms.txt
Solo deseo cambiar los 5,000 archivos que terminan en .CMS.TXT
Y que los archivos .TXT no tengan cambio.
Espero haberme explicado bien.
Entonces creo que basta con que en el comando del FOR cambies el *.txt por *.cms.txt. Quedaría:
for /f %%i in ('dir /b *.cms.txt ^| find "Respuesta"') do (
Ya me contarás.
Con eso último ha quedado perfecto y funciona de lujo.
Una última cosa: Al probar esto en mi equipo va todo bien, pero al querer ejecutar el comando en otro equipo con Windows XP no funicona. Supongo que los comandos del script no aplican a XP... ¿correcto?
Tiene que funcionar igual de bien (o de mal). De hecho yo lo estoy probando en un XP (le tengo mucho cariño a esa versión de Windows y la uso casi más que las posteriores). De modo que habrá que investigar un poco los mensajes que da el sistema. Si "comentas" poniéndole un "rem" delante el comando "@echo off" te sacará uno por uno los comandos que ejecuta y lo que ocurre con ellos. Si hay muchos archivos puede ser intratable pero si te creas un pequeño entorno de pruebas (pocos archivos o una carpeta diferente, editando el BAT) podrás averiguar lo que está ocurriendo. Si necesitas más ayuda no dudes en contármelo y si ya va todo bien cierra la pregunta.
No logro hacer que funcione en WP, no hace nada. En la ventana de comandos no muestra mas que las sentencias de comandos del bat.
Aun así cerraré la pregunta porque me ha sacado del problema. Haré la operación en otro equipo y voy a transferir los archivos cl equipo destino.
Muchas gracias por tu invaluable ayuda.
No me gusta dejar las cosas "a medias", de modo que, si no te importa, me gustaría aclarar porque no te funciona en XP. Te copio a continuación lo que me sale a mí al ejecutarlo en mi "entorno de pruebas" habiendo comentado la línea "@echo off" para que, si quieres, puedas comparar a ver si encuentras el error. Si no lo encuentras puedes hacer algo parecido (lo copias desde la ventana CMD y lo pones aquí usando el "snipett", icono <> de la barra auxiliar):
D:\BAT>type pgomez.bat rem @echo off Setlocal EnableDelayedExpansion cd \CarpOrig for /f %%i in ('dir /b *.cms.txt ^| find "Respuesta"') do ( set arch=%%i set arch=!arch:~0,-7!txt.cms.out echo ren "%%i" "!arch!" ) D:\BAT>dir \CarpOrig El volumen de la unidad D es ABR2003 El número de serie del volumen es: 10F6-62F9 Directorio de D:\CarpOrig 31/01/2017 18:32 <DIR> . 31/01/2017 18:32 <DIR> .. 18/08/2016 08:33 86.733 ChundaChunda.cms.txt 07/02/2016 19:17 91.119 NadaDeNada.kkk 13/11/2016 11:27 110.647 Pero que pasa.txt 18/08/2016 08:25 122.765 Respuesta.cms.txt 26/12/2016 12:05 3.247 Respuesta.txt 23/11/2016 17:02 70.412 Respuesta000001.cms.txt 23/11/2016 17:08 105.853 Respuesta000002.cms.txt 23/11/2016 17:02 68.872 Respuesta000005.cms.txt 20/06/2016 18:05 93.014 Tariro tariro.txt 12/10/2015 09:01 454 VayaPorDios.es.srt 10 archivos 753.116 bytes 2 dirs 30.125.682.688 bytes libres D:\BAT>pgomez D:\BAT>rem @echo off D:\BAT>Setlocal EnableDelayedExpansion D:\BAT>cd \CarpOrig D:\CarpOrig>for /F %i in ('dir /b *.cms.txt | find "Respuesta"') do ( set arch=%i set arch=!arch:~0,-7!txt.cms.out echo ren "%i" "!arch!" ) D:\CarpOrig>( set arch=Respuesta.cms.txt set arch=!arch:~0,-7!txt.cms.out echo ren "Respuesta.cms.txt" "!arch!" ) ren "Respuesta.cms.txt" "Respuesta.txt.cms.out" D:\CarpOrig>( set arch=Respuesta000001.cms.txt set arch=!arch:~0,-7!txt.cms.out echo ren "Respuesta000001.cms.txt" "!arch!" ) ren "Respuesta000001.cms.txt" "Respuesta000001.txt.cms.out" D:\CarpOrig>( set arch=Respuesta000002.cms.txt set arch=!arch:~0,-7!txt.cms.out echo ren "Respuesta000002.cms.txt" "!arch!" ) ren "Respuesta000002.cms.txt" "Respuesta000002.txt.cms.out" D:\CarpOrig>( set arch=Respuesta000005.cms.txt set arch=!arch:~0,-7!txt.cms.out echo ren "Respuesta000005.cms.txt" "!arch!" ) Ren "Respuesta000005.cms.txt" "Respuesta000005.txt.cms.out" D:\BAT>
Primero, con "type pgomez.bat", muestro el contenido del BAT. Luego, con "dir \CarpOrig" muestro los archivos que hay en mi carpeta de pruebas. Por último, con "pgomez", fuerzo la ejecución del BAT. Cuando el FOR encuentra algún archivo que contenga el texto "Respuesta" entre los que terminan en "cms.txt" ejecuta los comandos del DO asignando a la variable arch el nombre del archivo y luego retocándolo, para finalmente ejecutar el ECHO que simula el renombrado (si quitara el ECHO se haría el renombrado real).
Inténtalo si tienes un rato.
Te comento que en mi equipo (Windows 10) sigue funcionando bien (aunque necesito quitar el echo antes del ren de la penúltima línea).
EN el equipo con XP no funciona... pego aquí lo que muestra la ventana de comandos:
OJO.- el BAT lo tengo en la misma carpeta que los archivos, por lo que me brinco el paso de CD \Pruebas
C:\Pruebas>type comando.bat
rem @echo off
Setlocal EnableDelayedExpansion
for /f %%i in ('dir /b *.cms.txt ^| find "RESPUESTA_"') do (
set arch=%%i
set arch=!arch:~0,-7!txt.cms.out
ren "%%i" "!arch!"
)
C:\Pruebas>dir
El volumen de la unidad C no tiene etiqueta.
El número de serie del volumen es: 8853-8081
Directorio de C:\Pruebas
31/01/2017 09:36 a.m. <DIR> .
31/01/2017 09:36 a.m. <DIR> ..
31/01/2017 05:14 p.m. 181 comando.bat
12/12/2016 09:12 a.m. 201 RESPUESTA_MXOMADEL-20161209141106154.cms.txt
12/12/2016 09:12 a.m. 201 RESPUESTA_MXOMADEL-20161210060220720.cms.txt
14/12/2016 09:11 a.m. 201 RESPUESTA_MXOMADEL-20161213164042431.cms.txt
14/12/2016 09:11 a.m. 201 RESPUESTA_MXOMADEL-20161214060221620.cms.txt
15/12/2016 10:12 a.m. 201 RESPUESTA_MXOMADEL-20161214104145363.cms.txt
15/12/2016 10:12 a.m. 201 RESPUESTA_MXOMADEL-20161215060222717.cms.txt
7 archivos 1,387 bytes
2 dirs 127,774,650,368 bytes libres
C:\Pruebas>comando
C:\Pruebas>rem @echo off
C:\Pruebas>Setlocal EnableDelayedExpansion
C:\Pruebas>for /F %i in ('dir /b *.cms.txt | find "RESPUESTA_"') do (
set arch=%i
set arch=!arch:~0,-7!txt.cms.out
ren "%i" "!arch!"
)
C:\Pruebas>
Lo de quitar el echo de la última línea está claro que es necesario si se quiere que cambie el nombre a los archivos. Con el echo solo muestra el comando que se ejecutaría sin él.
Lo del XP es bien raro. He renombrado dos de mis archivos para utilizar el nombre de dos de los tuyos y me funciona correctamente. Parece obvio que lo que no funciona igual es el comando que está dentro del IN del FOR. En lugar del "dir" sin más que has ejecutado, prueba con
dir /b
dir /b *.cms.txt
dir /b *.cms.txt | find "RESPUESTA_"
Y muéstrame que te sale en cada uno de los casos.
No acabo de entender como podría afectar, pero tal vez no estuviera de más ver la versión de Windows XP (comando "ver") y la "configuración regional" (pantallas del programa intl. Cpl). Pensé que tal vez algunas configuraciones no permitan la presencia de guiones "-" en el nombre de los archivos pero no encuentro nada que avale esa "intuición".
Esto es lo que me sale después de los comandos:
C:\Pruebas>dir /b
comando.bat
Nuevo Documento de texto.txt
RESPUESTA.cms.txt
RESPUESTA_MXOMADEL-20161210060220720.cms.txt
RESPUESTA_MXOMADEL-20161213164042431.cms.txt
RESPUESTA_MXOMADEL-20161214060221620.cms.txt
RESPUESTA_MXOMADEL-20161214104145363.cms.txt
RESPUESTA_MXOMADEL-20161215060222717.cms.txt
C:\Pruebas>dir /b *.cms.txt
RESPUESTA.cms.txt
RESPUESTA_MXOMADEL-20161210060220720.cms.txt
RESPUESTA_MXOMADEL-20161213164042431.cms.txt
RESPUESTA_MXOMADEL-20161214060221620.cms.txt
RESPUESTA_MXOMADEL-20161214104145363.cms.txt
RESPUESTA_MXOMADEL-20161215060222717.cms.txt
C:\Pruebas>dir /b *.cms.txt | find "RESPUESTA_"
Comando o nombre de archivo erróneo
C:\Pruebas>Muy raro que después de la ultima instrucción no encuentre resultados.
Olvidé decirte que el equipo es WP (Versión 5.1.2600) con Service pack 3.
Por otra parte, te muestro el resultado el "find" en el equipo donde si funciona el script.
Aquí sí me arroja resultado:
C:\Users\fgomez\Desktop\Pruebas>dir /b *.txt.cms.out | find "RESPUESTA_"
RESPUESTA_MXOMASIP-20170131124042988.txt.cms.out
RESPUESTA_MXOMASIP-20170131124044161.txt.cms.out
RESPUESTA_MXOMASIP-20170131161026142.txt.cms.out
RESPUESTA_MXOMASIP-20170131161036300.txt.cms.out
C:\Users\fgomez\Desktop\Pruebas>
Tu versión es la misma que la mía. Me da la impresión de que no localiza el comando "find" o que tiene algún problema con ese comando, aunque si no existiera o no estuviera en el "path" debería decir algo como "no se reconoce como un comando interno o externo". Prueba a teclear "find /?" en la ventana CMD a ver que dice. Si sale correctamente la información del FIND prueba entonces con otro literal dentro del find del dir /b, por ejemplo
dir /b *.cms.txt | find "2016"
en lugar de
dir /b *.cms.txt | find "RESPUESTA_"
A ver si en este caso sale algo.
Si reconoce el find como comando.
Pero ni buscando "2016" arroja algo.
C:\Pruebas>find /?
Busca una cadena de texto en uno o más archivos.
FIND [/V] [/C] [/N] [/I] [/OFF[LINE]] "cadena" [[unidad:][ruta]archivo[ ...]]
/V Muestra todas las líneas que no tengan la cadena especificada.
/C Muestra sólo el número de líneas que contienen la cadena.
/N Muestra el número de línea de cada línea.
/I Omite mayúsculas/minúsculas al buscar una cadena.
/OFF[LINE] No omite archivos con el atributo "sin conexión" establecido.
"cadena" Especifica el texto que se desea buscar.
[unidad:][ruta]archivo
Especifica el o los archivos a buscar.
Si no se especifica una ruta, FIND busca el texto que se escriba en el símbolo
del sistema o que se canalice desde otro comando.
C:\Pruebas>dir /b *.cms.txt | find "2016"
Comando o nombre de archivo erróneo
C:\Pruebas>
Si quito la pipa si funciona el find:
C:\Pruebas>dir /b *.cms.txt find "2016"
RESPUESTA.cms.txt
RESPUESTA_MXOMADEL-20161210060220720.cms.txt
RESPUESTA_MXOMADEL-20161213164042431.cms.txt
RESPUESTA_MXOMADEL-20161214060221620.cms.txt
RESPUESTA_MXOMADEL-20161214104145363.cms.txt
RESPUESTA_MXOMADEL-20161215060222717.cms.txt
C:\Pruebas>
Pero: al quitar la pipa en el bat, me tira error:
C:\Pruebas>comando
C:\Pruebas>rem @echo off
C:\Pruebas>Setlocal EnableDelayedExpansion
C:\Pruebas>for /F %i in ('dir /b *.cms.txt find "RESPUESTA_"') do (
set arch=%i
set arch=!arch:~0,-7!txt.cms.out
ren "%i" "!arch!"
)
Demasiados parámetros - find
C:\Pruebas>
Me he equivocado.
Sin la pipa si me arroja información, pero el find no funciona.
Si te fijas, me enlista todos los archivos que tiene la carpeta (es decir, solo funciona el dir)
Aquí doy la instrucción de que busque archivos con la palabra paco
El resultado: me devuelve todos los archivos.
C:\Pruebas>dir /b *.cms.txt find "paco"
Nuevo Documento de texto.cms.txt
RESPUESTA.cms.txt
RESPUESTA_MXOMADEL-20161210060220720.cms.txt
RESPUESTA_MXOMADEL-20161213164042431.cms.txt
RESPUESTA_MXOMADEL-20161214060221620.cms.txt
RESPUESTA_MXOMADEL-20161214104145363.cms.txt
RESPUESTA_MXOMADEL-20161215060222717.cms.txt
C:\Pruebas>
Mientras intentamos averiguar por qué no parece funcionar la pipa se me ocurre que pruebes con esto:
@echo off Setlocal EnableDelayedExpansion cd \CarpOrig dir /b *.cms.txt > temp.txt for /f %%i in ('findstr "RESPUESTA_" temp.txt') do ( set arch=%%i set arch=!arch:~0,-7!txt.cms.out ren "%%i" "!arch!" )
Esta opción pasa por generar un archivo intermedio, TEMP.TXT, con los nombres de los archivos que cumplen las condiciones del DIR.
He cambiado de FIND a FINDSTR porque el FIND sacaba también un archivo de nombre ----------- que no sé bien de donde sale.
Tremenda Solución.
Este script funciona perfecto!
Te agradezco tremendamente la dedicación que le has puesto a este problema.
Sinceramente deseo poder corresponderte en algún futuro de la misma manera.
¡Me alegro mucho, mucho!
Pero todavía no sé por qué no funciona la pipa en tu entorno. Intentaré indagar un poco en ese sentido y si descubro algo ya te lo contaré.
Y no te preocupes por lo de corresponderme o no de la misma manera, si no es a mí puede ser a otros. Una de las cosas que más me gusta de la red es la posibilidad que ofrece a la ayuda verdaderamente desinteresada (aunque nunca es del todo desinteresada, siempre hay un beneficio aunque solo sea en el placer que le da al que la ofrece el hecho mismo de ofrecerla o, en mi caso, el proceso de encontrar una solución).
Una última prueba: teclea directamente en una ventana CMD el carácter "pipa" seguido de retorno y cuéntame cuál es la respuesta. Y hazlo de dos maneras, una utilizando el teclado para conseguir el carácter y otra mediante la combinación Alt + 1 + 2 + 4 (supongo que conoces esa forma de generar caracteres a partir del código ASCII, mantienes pulsada la tecla Alt mientras en el teclado numérico pulsas sucesivamente las teclas de 1, 2 y 4 y luego levantas el dedo de la tecla Alt). Debería decir "No se esperaba | en este momento."
Perdona que sea tan insistente, pero ¡es que lo soy!
He encontrado algo que podría dar alguna pista. Cuando tengas un rato ejecuta en el XP los siguientes comandos:
reg query "HKCU\Software\Microsoft\Command Processor" /v AutoRun Reg query "HKLM\Software\Microsoft\Command Processor" /v AutoRun
Según he podido leer el efecto previsto para la pipa es ejecutar un nuevo CMD.EXE y parece que el parámetro AutoRun de Command Processor puede modificar el comportamiento de los CMD.EXE autoejecutados.
Al poner la piña, efectivamente me responde lo que comentas:
C:\Documents and Settings\sacn>|
No se esperaba | en este momento.
C:\Documents and Settings\sacn>
Voy a intentar lo del registro y te platico
Imagino que quieres decir que para los dos comandos da el mismo resultado, pero ¿cuál era ese resultado? ¿Las claves correspondientes están vacías (ese sería el peor resultado porque querría decir que hay que buscar otra explicación)?
No puedo entender que ha pasado.
Hoy volvi a correr el script y ha funcionado de maravilla.
No he realizado cambio alguno, todo igual que desde un principio.
HE querido mostrar a mi jefe el problema y, como siempre ocurre en los casos en que quieres demostrar algo, todo ha funcionado bien.
Ahora comprendo lo que mis usuarios sienten.
Pues nos quedamos sin "entorno de pruebas" para intentar indagar algo más en el asunto. ¿Podría haber diferencias entre abrir la ventana CMD con un usuario o con otro? Por ejemplo con un usuario del grupo de administradores y otro que no lo sea. Si vuelves a descubrir algo que permita reproducir el "mal funcionamiento" me avisas, ¿vale?
- Compartir respuesta