2

I am trying to replace URL encodings (e.g. %20 as a placeholder for a space) with their corresponding ASCII values in all filenames in a Windows folder and its subfolders.

If have a simple .bat file that can accomplish this, but it has limitations:

@echo off
Setlocal enabledelayedexpansion

Set "Pattern0=%%20"
Set "Replace0= "

Set "Pattern1=%%27"
Set "Replace1='"

Set "Pattern2=%%28"
Set "Replace2=("

Set "Pattern3=%%29"
Set "Replace3=)"

Set "Pattern4=%%5B"
Set "Replace4={"

Set "Pattern5=%%5D"
Set "Replace5=}"

For %%# in ("D:\Dropbox\Music\*.mp3") Do (
    Set "File=%%~nx#"
    Ren "%%#" "!File:%Pattern0%=%Replace0%!"
    Ren "%%#" "!File:%Pattern1%=%Replace1%!"
    Ren "%%#" "!File:%Pattern2%=%Replace2%!"
    Ren "%%#" "!File:%Pattern3%=%Replace3%!"
    Ren "%%#" "!File:%Pattern4%=%Replace4%!"
    Ren "%%#" "!File:%Pattern5%=%Replace5%!"
)

Pause&Exit

There are two major limitations I'd like to fix:

  1. It only checks the ..\Music\ folder root. I'd like it to look at files in subdirectories, too.
  2. It exits the For loop as soon as one of the renames are executed (all %20's replaced first pass, for example, but nothing else).

And surely there is a better way to specify the encodings and their replacements (rather than variable pairs for each), but that's a nice-to-have feature.

These encodings always take the form %XX, where X are hexadecimal values.

1 Answers1

3
  1. To solve directory recursive search, you could use dir /s /b instead
FOR /F "delims=" %%# in ('dir /s /b "D:\Dropbox\Music\*.mp3"') Do (
...
)
  1. Do not rename the file any time, only after all replacements
FOR /F "delims=" %%# in ('dir /s /b "D:\Dropbox\Music\*.mp3"') Do (
   set "file=%%~#"
   set "file="!File:%%20= !"
   set "file="!File:%%28=(!"
   ...
   move "%%~#" "!file!"
)

I'm using move here, because it works with full pathnames, too

  1. To solve problems with exclamation marks in filenames/paths, you need to toggle delayed expansion
setlocal DisableDelayedExpansion
FOR /F "delims=" %%# in ('dir /s /b "D:\Dropbox\Music\*.mp3"') Do (
   set "file=%%~#"

   setlocal EnableDelayedExpansion
   set "file="!File:%%20= !"
   set "file="!File:%%28=(!"
   ...
   move "%%~#" "!file!"
   endlocal
)
jeb
  • 78,592
  • 17
  • 171
  • 225
  • Thanks!! It looks like the only step left to me is to fill in the specific renames manually, y/n? E.g. next line would (presumably) be `set "file="!File:%%29=)!"` -- and so forth? If that's true, I'm wondering if there's a way to avoid one row of code for any/every ASCII encoding (originating from URL encodes)? Again, we know the values to match are always in the format `%HH` where H = a hexadecimal char. – Derek Clark May 29 '21 at 08:58
  • 1
    @DerekClark Yes, only add the missing replacements. You could also search for the percent sign and fetch the next two characters and convert them, BUT that is not trivial – jeb May 29 '21 at 10:27
  • Noted, and thank you once again. I'm familiar with the conventions of regular expressions, but aware that knowledge may not transfer well when dealing with Windows scripts – Derek Clark Jun 01 '21 at 08:48