Renombrar archivos con un script en .bat
No tengo mucho conocimiento en programación, pero se algo, lo básico, lo que quiero hacer es un script en batch el cual renombre varios archivos dentro de una carpeta por ejemplo :
Digamos que tengo 10 archivos que se llaman
hola_0089738431zip
amigo_0028374.zip
Y así, lo que quiero que el script haga es que le quite el guion y los números que le siguen y que queden de la siguiente manera
Hola
Amigo
Sin extensión, eso seria el primer script, para el segundo script necesito que a los mismos archivos le agregue la extensión (o cualquiera que le quiera dar) para que queden de este modo :
hola.zip
amigo.zip
Si fueran scripts independientes se los agradecería muchísimo
2 respuestas
No sé si la pregunta está cerrada y, por tanto, no sé si te llegará esta otra respuesta, pero la pongo por si acaso.
Si te sigue interesando eliminar también el "_" del nombre de los archivos, te propongo lo siguiente para el primer bat :
for /f "tokens=1,2,3 delims=_." %%a in ('dir /b *_*.*') do (ren %%a_%%b.%%c %%a)
Ejecutando el BAT en la carpeta donde estén los archivos a renombrar.
En este caso los archivos quedarían sin extensión (y sin "_" en el nombre) por lo que habría que retocar la propuesta de javier en el sentido siguiente (asumiendo que se les quiere asignar la extensión DAT):
ren *. *.dat
No he entrado en el tema de que la primera letra del nombre definitivo sea mayúscula porque no sé si es importante. Si lo fuera dínoslo y ya veríamos como se podría hacer.
Que tal, muchas gracias por tu respuesta, aun no le eh calado, pero mi intención es también la siguiente, poner ese bat en el path de Windows para poder ejecutarlo donde sea, así que el nombre del directorio seria una variable de donde me encuentre en ese momento por ejemplo :
Digamos que estoy en C:\user y abro un cmd desde este path, entonces al llamar al bat que este me detecte automático el directorio y haga la operación.
Espero haberme explicado bien, y por lo que comentas de que si el nombre es en mayúsculas te puedo decir que no, casi siempre son minúsculas
Si en el propio bat no se especifica ninguna carpeta/directorio las acciones se realizarán sobre la carpeta "actual" con independencia de que el BAT esté en otra carpeta. En ese sentido, por tanto, no debería haber ningún problema.
Pruébalo y me dices si te funciona correctamente o si hay que hacer algún retoque.
Que tal, ya probé la línea de código que me comentaste arriba :
for /f "tokens=1,2,3 delims=_." %%a in ('dir /b *_*.*') do (ren %%a_%%b.%%c %%a)
Y así tal cual esta cuando la ejecuto en un bat me sale el error :
"The system cannot find the path specified"
despues de eso la modifique de esta manera para ver si funcionaria :
chdir = dir
for /f "tokens=1,2,3 delims=_." %%a in (%dir% /b *_*.*) do (ren %%a_%%b.%%c %%a)
y me sale el error
"The system cannnot find the path specified"
"The system cannot find the file /b"
No lo entiendo.
Prueba el comando dir /b *_*.* en una ventana CMD a ver que te dice. Supongo que copiaste y pegaste el texto del FOR porque las comillas simples que delimitan el comando incluido en los paréntesis del IN son importantes.
También puedes probar el FOR directamente, sin incluirlo en un bat:
for /f "tokens=1,2,3 delims=_." %a in ('dir /b *_*.*') do (echo ren %a_%b.%c %a)
A ver si también te da error.
Ya me contarás.
GGG
Ya logre conseguir el path con el siguiente comando :
for /f "tokens=1,2,3 delims=_." %%a in (".\ /b *_*.*") do (ren %%a_%%b.%%c %%a)
pero al ejecutarlo me da un error de :
(ren \ /b *_*.* \ /b * )
The syntax of the command is incorrect.
Creo que estamos líando el asunto. En el paréntesis del IN tiene que ir un comando que liste el directorio que nos interesa y eso no puede conseguirse con comillas dobles sino con comillas simples.
Empecemos de nuevo. ¿Con qué versión de Windows estás trabajando (lo digo por si hubiera alguna diferencia, la mía es XP SP3 o también Windows 7). Supongamos que la lista de archivos que quieres renombrar es la siguiente (es la lista de archivos con la que yo estoy haciendo las pruebas):
Adios.muchachos.adios_89764.apk
hola.y.adios_02335625.apk
kakita.de.la.vakita_01.apk
Otro.mas_0123.apk
pepito_2223344.apk
temp_00.apk
Y lo que quieres conseguir es que se queden así:
Adios. Muchachos. Adios
hola.y.adios
kakita.de.la.vakita
Otro. Mas
pepito
temp
Para ello créate un BAT que contenga exactamente esta línea:
for /f "tokens=1,2,3 delims=_" %%a in ('dir /b *_*.*') do (echo ren %%a_%%b %%a)
Comprobarás que la he cambiado porque ahora los nombres de archivo pueden tener puntos intermedios, además del separador de la "extensión" del archivo. Además he sustituido el comando "ren" por "echo ren" para que no ejecute el renombrado durante las pruebas.
Ejecuta el bat desde el directorio (carpeta o folder, como quieras llamarle) en el que se encuentren los archivos y me dices que pasa. Si no funciona correctamente hazme llegar un pantallazo del resultado, de la forma que se te ocurra (por ejemplo subiéndolo a "la nube" y facilitándome el enlace).
Ya con la línea de código que me proporcionaste ya me funciono a la perfección, ahora solo hay un detalle que no había contemplado, si la apk tiene dos guiones me sale un error cuando ejecuto el bat :
_________________________________________________________________________
for /f "tokens=1,2,3 delims=_" %%a in ('dir /b *_*.*') do (ren %%a_%%b %%a)
apk : whatsapp.com_jijo_287373.apk
Error : The system cannot find the file specified
____________________________________________________________
¿Entonces no se podría agregar que tomara el primer guion bajo de derecha a izquierda?
Nota : Este error que me da en la pantalla del cmd solo dice eso, nada más, por eso no creí necesario subirlo a la nube ya que es tal cual como te lo puse arriba
Mi SIstema Operativo : Windows 8.1
Efectivamente el error está claro, porque para ese caso el ren del DO sería:
ren whatsapp.com_jijo_287373 whatsapp.com_jijo
y no existe el archivo whatsapp.com_jijo_287373
Con carácter general no se me ocurre un método para hacer lo que dices (borrar el nombre a partir del primer guión bajo de derecha a izquierda porque el FOR siempre va de izquierda a derecha). Voy a seguir pensando en el asunto, pero mientras tanto el siguiente código debería funcionar correctamente con nombres que contengan hasta un máximo de seis guiones bajos:
@echo off
for /f "tokens=1,2,3,4,5,6 delims=_" %%a in ('dir /b *_*.*') do (call :renombrar %%a %%b %%c %%d %%e %%f)
goto :fin
:renombrar
if "%3"=="" (echo ren %1_%2 %1&goto :eof)
if "%4"=="" (echo ren %1_%2_%3 %1_%2&goto :eof)
if "%5"=="" (echo ren %1_%2_%3_%4 %1_%2_%3&goto :eof)
if "%6"=="" (echo ren %1_%2_%3_%4_%5 %1_%2_%3_%4&goto :eof)
if "%7"=="" (echo ren %1_%2_%3_%4_%5_%6 %1_%2_%3_%4_%5&goto :eof)
echo ren %1_%2_%3 %1_%2
goto :eof
:fin
Como en la ocasión anterior he "comentado" el comando de renombrado, precediéndolo de un "echo", para que muestre el texto que se ejecutaría cuando se elimine el "echo". La ampliación del máximo de guiones se haría retocando consecuentemente la cláusula TOKENS del FOR, los parámetros del CALL y la batería de IF en la rutina :renombrar.
En mi entorno lo he probado sobre estos archivos:
ren Adios.muchachos.adios_89764.apk Adios.muchachos.adios
ren Copia.de_hola.y.adios_02335625.apk Copia.de_hola.y.adios
ren Copia_Adios.muchachos.adios_89764.apk Copia_Adios.muchachos.adios
ren Copia_de_kakita_de_la.vakita_01.apk Copia_de_kakita_de_la.vakita
Ren hola.y.adios_02335625.apk hola.y.adios
Ren kakita. De. La.vakita_01. Apk kakita. De. La. Vakita
Ren Otro.mas_0123. Apk Otro. Mas
ren pepito_2223344. Apk pepito
ren temp_00. Apk temp
Como puedes ver funciona correctamente.
Con esto debería quedar zanjada esta pregunta (si encontrase un método general más elegante ya lo diría, pero no veo claro cómo podría abordarlo). Ahora podríamos pasar a la otra consulta y yo empezaría por intentar aclarar si el INSTALL de las apk's codifica distintos valores de ERRORLEVEL según el resultado del intento de instalación. Pero la forma de hacerlo te la contaré en el otro hilo.
Ya me dirás.
Dos cosas: el BAT de mi mensaje anterior admite un máximo de cinco guiones bajos y no seis como decía y ya he encontrado una forma que funciona con carácter general aunque no es demasiado "elegante". Sería esta:
@echo off
Setlocal EnableDelayedExpansion
for /f "tokens=1,2,* delims=_" %%a in ('dir /b *_*.*') do (call :tratar %%a %%b %%c)
goto :fin
:tratar
set c1=%1
set c2=%2
set c3=%3
if "%c3%"=="" (echo ren %c1%_%c2% %c1% & goto :eof)
set nd=%c1%
set nt=%c2%_%c3%
:bucle
for /f "tokens=1,2,* delims=_" %%x in ("!nt!") do (
set c1=%%x
set c2=%%y
set c3=%%z
if "%c3%"=="" (echo ren !nd!_%c2% !nd! & goto :eof)
set nt=%c3%
set nd=!nd!_%c2%
goto :bucle
)
:Fin
Por otra parte he descubierto de forma casual que ninguna de las soluciones barajadas aquí funciona si alguno de los archivos tiene paréntesis en el nombre. Creo que el entorno BAT trata los paréntesis de forma no transparente y eso provoca los problemas.
El primer script para quitar el guion y la extensión ya quedo, de hecho fue una excelente respuesta la ultima ya que no limita el numero de guiones de la apk.
Ya por ultimo solo faltaría ponerles de nuevo la extensión, con esta línea
ren *. *.apk
cuando la ejecuto el cmd me muestra el error
"The syntax of the command is incorrect."
teniendo en cuenta que los archivos a renombrar serian :
com.aa.generalad_aptiveapps
com.etermax. Preguntados. Lite
Y quisiera que quedaran así :
com.aa.generalad_aptiveapps.apk
com.etermax.preguntados.lite.apk
Gracias
Investigando un poco logre conseguir renombrar los archivos con esta línea
for /f "tokens=1,2 delims=" %%a in ('dir /b *.*') do (call :rename %%a)
goto :fin
:rename
ren %1 %1.apk
goto :eof
:fin
El detalle es que este script se tiene que ejecutar varias veces por día, y cada que lo ejecuto la apk se le anexa la extensión .apk por ejemplo :
com.aa.generaladaptiveapps.apk.apk.apk.apk
habria modo de hacer una comprobacion de que si el archivo ya tiene la extencion .apk ya no se la ponga ?
En primer lugar si el comando
ren *. *.apk
te da el error
The syntax of the command is incorrect.
Es porque, en ese momento, no hay ningún archivo sin extensión en esa carpeta. Si repites el comando cuando haya archivos de este tipo se ejecutará sin problemas.
De modo que esta aclaración elimina la necesidad de detectar la presencia de la extensión apk de tu siguiente entrada, solo se renombrarán los archivos sin extensión y no se añadirá ".apk" a los que ya la tienen.
Con esto debería, creo yo, cerrarse esta pregunta.
Voy a ver que me has dicho en la otra.
¡Muchas Gracias!
Por tu paciencia hasta que esta pregunta se resolviera, la verdad eres una persona como pocas y con gran conocimiento, sigue así.
Saludos
Antes que nada quiero agradecerte tus buenas palabras. La verdad es que me gusta resolver problemas de este tipo, aunque no siempre pueda.
Pero también quiero reconocer que, tal como me indicas en el otro hilo, el renombrado de archivos sin extensión para añadirles una extensión al nombre (con el comando "ren *. *.apk" por ejemplo) no funciona para los archivos sin extensión que contienen puntos en el nombre. La propia sintaxis del comando los excuye del renombrado (pues no cumplen la condición "*.", es decir, "cualquier cosa con punto seguida de nada"). Si en el directorio donde se ejecuta hay alguno que la cumple se aplicará el renombrado solo a los que la cumplen (sin extensión y sin puntos en el nombre) y no dará error pero si ninguno la cumple (si no hay ningún archivo sin extensión que no tenga puntos en el nombre) saldrá el mensaje de error
"The syntax of the command is incorrect."
"La sintaxis del comando no es correcta." (si la versión del SO es en español).
Para tus necesidades concretas creo que podrías eliminar el que llamabas en tu mensaje original "segundo script" incorporando la extensión que desees al script que estamos tratando, sustituyendo, por ejemplo:
ren %c1%_%c2% %c1%
Por
ren %c1%_%c2% %c1%. Apk
Si esto no es posible en tu caso te sugiero que abras otra consulta y vemos como se podría resolver con carácter general el renombrado de archivos sin una extensión determinada para incorporarles esa extensión. Tendría que ser este el planteamiento porque un archivo con puntos en el nombre no puede considerarse, propiamente, un archivo sin extensión. Es una consecuencia del diseño original del nombre de archivos en MSDOS que luego se "relajó" un poco para permitir más de un punto en el "nombre completo" y extensiones de más de tres caracteres, pero que paga este "peaje".
Ha sido un placer poder echarte una mano.
- Compartir respuesta
El scripting con MSDOS está bastante limitado, sobre todo en cuanto a manejo de nombres de fichero.
Lo más cercano que se me ocurre a la solución que pides es esto:
- Teniendo dos ficheros en una carpeta específica (voy a usar de ejemplo c:\ejemplo\):
c:\prueba\HOLA_00224234.txt
c:\prueba\ADIOS_00353453.txt
** Crea un fichero paso1.bat con el siguiente script:
ren C:\ejemplo\*_*.txt *_
Esto cortará los nombres de los ficheros hasta el último carácter que hemos especificado ('_') en el nombre de destino, pero no es posible cortar ese carácter ya que no conocemos el anterior. El resultado será éste:
c:\prueba\HOLA_
c:\prueba\ADIOS_
** Para el cambio de extensión, bastante mas fácil. Crea un fichero paso2.bat con el siguiente script:
ren C:\ejemplo\*_ *.dat
(donde 'dat' es la extensión que quieras poner)
El resultado será éste:
c:\prueba\HOLA_.dat
c:\prueba\ADIOS_.dat
- Compartir respuesta