2

I need a little help with a .bat I'm using to rename files that contain multiple words. I get a few hundred downloaded into a folder every week and It's getting a little time consuming to use something like the bulk rename utility.

What I mean by multiple words is that one file might look like:

The Hellblazer 021 (2018) (2 covers) (Digital) (Son of Ultron-Empire).cbr

and I'd like to have something that'd change it to:

The Hellblazer 021 (2018) (digital) (Son of Ultron-Empire).cbr

What I currently use handles changing something to lower case just fine.

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET old=Digital
SET new=digital
for /f "tokens=*" %%f in ('dir /b *.*') do (
  SET newname=%%f
  SET newname=!newname:%old%=%new%!
  move "%%f" "!newname!"
)

and I can just add another piece under that to change different words to my heart's content. The trouble is, I can't get it to recognise spaces with something like (2 covers), and thus remove it entirely from the filename.

Does anyone have any ideas?

*edited for clarification

gosunkugi
  • 23
  • 4
  • 3
    A filename is usually in the form `name.extension`, can you please provide a more accurate example of an input filename and its matching required output filename. That should be done by [editing your question](https://stackoverflow.com/posts/50551916/edit), not responding in this comment area. – Compo May 27 '18 at 12:14
  • 2
    If it has to be on windows, you could always explore the extra functions and capabilities you would get with powershell or vbscript – Spangen May 27 '18 at 12:15
  • 1
    `set` variable substituation is a bit strange: the string to be replaced is case*in*sensitive. So as strange as it may look, the following works as you want: `SET newname=!newname:%new%=%new%!`. So it will also change `DIGITAL` or `DiGiTaL` to `digital` (just a side note to prepare you for surprises) – Stephan May 27 '18 at 17:39
  • By what criteria do you determine the part to remove from the file name? is it always `(2 covers)`? – aschipfl May 28 '18 at 05:49

1 Answers1

0

Help of cmd.exe output on running in a command prompt window cmd /? explains on last page with last paragraph that file names containing a space or one of these characters &()[]{}^=;!'+,`~ must be enclosed in double quotes.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir * /A-D-H /B 2^>nul') do (
    set "NewName=%%I"
    set "NewName=!NewName:Digital=digital!"
    set "NewName=!NewName: (2 covers)=!"
    move "%%I" "!NewName!"
)
endlocal

See also How to set environment variables with spaces?

On the command lines with SET the string set is argument 0 and NewName=... is argument 1. The entire argument string must be enclosed in double quotes, especially on containing space or one of these characters &()[]{}^=;!'+,`~<|>.

Well, the command SET has a very special argument string parsing which makes it often possible to omit the double quotes even on assigning a string value with spaces and brackets to an environment variable. But the command block executed by FOR starts with (. The next ) found by Windows command processor on parsing entire command block before executing the command FOR is interpreted as end of command block, except ) is within a double quoted string or is escaped with ^ to be interpreted as literal character instead of end of a command block. For that reason it is highly recommended to enclose an argument string always in double quotes if it is not 100% guaranteed that the argument string does not contain command line critical characters.

One more note: File names containing one or more ! would not be processed correct by the above batch file because of enabled delayed environment variable expansion.

The solution is avoiding usage of delayed expansion by using a subroutine.

@echo off
for /F "eol=| delims=" %%I in ('dir * /A-D-H /B 2^>nul') do call :RenameFile "%%I"
goto :EOF

:RenameFile
set "NewName=%~1"
set "NewName=%NewName:Digital=digital%"
set "NewName=%NewName: (2 covers)=%"
move %1 "%NewName%"
goto :EOF

See also Where does GOTO :EOF return to?

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • move /?
  • set /?
  • setlocal /?
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • That works beautifully! Thank you so much. I knew that it somehow involved quotes but I didn't understand the syntax of putting them there. – gosunkugi May 27 '18 at 15:36