¿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

Respuesta
1

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>

Solo se me ocurre que no reconozca la "pipa", el carácter |

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

¿Has podido mirar lo del registro?

Corrí los comandos, pero el resultado es el mismo.

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?

Tenlo por seguro que si se presenta de nuevo te avisaré de inmediato.

Ahora me ha entrado la duda de si el mal funcionamiento se ha debido a una falla propia del SO del equipo.

Esta "respuesta" es solo para que no me aparezca este hilo como pendiente de respuesta. Me queda claro que si volviera a darse la situación de no funcionamiento en XP (o alguna asimilable a ella) me avisarías.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas