4

I have a folder containing a large number of files. A lot of the filenames have '%' and/or '&' characters in them.

e.g. Test&doc.pdf
e.g Test%doc.doc

Is there a quick way I could remove the '%' and '&' characters using a windows batch file, vbscript or something similar?

All help will be greatly appreciated.

Thanks.

Riain McAtamney
  • 6,342
  • 17
  • 49
  • 62
  • The folder is on a remote server that I dont have access to. So I want to give the person who does have access a script that can just be ran once. – Riain McAtamney Dec 13 '10 at 14:31
  • I guess it doesn't have to be a batch file. It could be a vbscript or something similar. I'll update question. – Riain McAtamney Dec 13 '10 at 15:51

3 Answers3

3

Here's how you can do it in batch (in case you're curious). The big limitation is that if you have filenames with more than one percent sign, it won't work because the shell expands it to a variable. I don't know immediately how to fix that.

It starts from whatever directory the script is in, and works recursively over all subdirectories.

@echo off

setlocal enabledelayedexpansion
for /f "usebackq delims=" %%N in (`dir /s /b`) do (
  set var=%%~nN
  set var=!var:^&= !
  set var=!var:%%= !

  if not "!var!"=="%%~nN" (
    if not exist "%%~dpN!var!%%~xN" (
      echo "%%N" --^> "!var!%%~xN"
      ren "%%N" "!var!%%~xN"
    ) else (
      echo File "!var!%%~xN" ^(from %%N^) already exists.
    )
  )
)

E.g., prints output like this:

C:\batch\schar>schar
"C:\batch\schar\Test%doc.doc" --> "Test doc.doc"
"C:\batch\schar\Test%doc.pdf" --> "Test doc.pdf"
File "Test doc.pdf" (from C:\batch\schar\Test&doc.pdf) already exists.
"C:\batch\schar\subdir\FILE%here" --> "FILE here"
indiv
  • 17,306
  • 6
  • 61
  • 82
  • I tested it and it works also with multiple percent signs, but it fails with exclamaton marks and carets. – jeb Dec 14 '10 at 09:05
  • @jeb: Thanks for checking. The more I look into it, the more I realize what an incredibly difficult problem this is to solve. I just can't figure out how to stop the shell from evaluating special characters in a string. This answer has so many limitations that I should probably just delete it. If someone can produce a batch solution without character limitations, I'll be massively impressed. – indiv Dec 14 '10 at 18:39
  • I hope, my solution can handle all characters without limitations – jeb Dec 15 '10 at 15:56
3

@indiv

If someone can produce a batch solution without character limitations, I'll be massively impressed.

Ok, I'll try.

@echo off

setlocal DisableDelayedExpansion
for /f "usebackq delims=" %%N in (`dir /s /b`) do (
  set var=%%~nxN
  setlocal EnableDelayedExpansion
  set "org=!var!"
  set "var=!var:&= !"
  set "var=!var:%%= !"

  if not "!var!"=="!org!" (
    if not exist "%%~dpN!var!" (
      echo "!org!" --^> "!var!"
      ren "!org!" "!var!"
    ) else (
      echo File "!var!" ^(from !org!^) already exists.
    )
  )
  endlocal
)

The trick is, to toggle the delayed expansion, because expanding of for-loop-vars (%%N) should be done without delayed expansion, else you lose the exclamation marks, and got problems with carets. But to handle and modify the strings you should use delayed expansion.

But why? The answer is to understand the phases of the batch parser.

I tried to explain it here. how-does-the-windows-command-interpreter-cmd-exe-parse-scripts

Community
  • 1
  • 1
jeb
  • 78,592
  • 17
  • 171
  • 225
  • Nice job, it is better than my solution. It has a problem with `Test^!doc.xls`, where it's interpreting the caret as an escape character for `!`. It produces the substitution `Test doc.xls` when there should be 2 spaces. The `ren` command is also problematic with filenames like `F%ILE%he%re`. The substitution works, producing `F ILE he re`, but the rename doesn't work because the first argument to `ren` has unescaped `%`. I don't think there's an easy solution to escaping special characters in batch, or suppressing their evaluation like `'` in perl. – indiv Dec 15 '10 at 16:28
  • The renaming of F%ILE%he%re works, because the expansion with ren "!org!" is safe, because no more parsing is done after the delayed expansion. In my batch also a "f%test^!doc.xls" is renamed successful to "f test^!doc.xls" – jeb Dec 15 '10 at 18:16
2

I've quickly thrown that together and didn't test it, but this VBScript should do the trick. Tell me if you need fancy stuff like folder recursive replacing etc.

Set objFSO = CreateObject("Scripting.FileSystemObject")

'Your folder here
objStartFolder = "X:\MYFOLDER"

Set objFolder = objFSO.GetFolder(objStartFolder)
Set regEx = New RegExp

'Your pattern here
regEx.Pattern = "[&%]" 

Set colFiles = objFolder.Files
For Each objFile in colFiles
    objFile.Rename(regEx.Replace(objFile.Name, "")
Next
Jules
  • 1,352
  • 7
  • 19