How to deal with ampersand in folder and/or file names in Windows batch? (I can't control file or folder name)

2.5k Views Asked by At

I have been doing a lot of reading and can't quite find an exact answer to my question. I have seen similar posts but not exactly this.

I have a program that generates names of files like:

d:\a and b\1 and 2.mkv
d:\a & b\1 & 2.mkv
d:\aandb\1and2.mkv

The point being is I can't control the output of the folder name or file name. I have a post processing script that takes that fully qualified file and runs commands on it. I can't seem to correctly call my post processing script that will correctly handle the fully qualified filename when the fully qualified filename could be any of the examples listed. Because I can't control the folder or file name, escaping the ampersand won't help. I have tried about ever combination of variables while using !variable! or %variable% and I can't seem to come up with a way that will handle any combination of folder or filename with ampersands or spaces in them.

How do I correctly pass the fully qualified filename to another batch file so that it correctly interprets the fully qualified filename whether it has spaces oe ampersands or doesn't have them? Just one of the examples:
test.cmd "A & B\1 & 2.mkv"

where test.cmd

@echo off
@setlocal EnableDelayedExpansion

@set TARGETDRIVE=%~d1
@set TARGETPATH=%~p1
@set TARGETNAME=%~n1
@set TARGETEXTENSION=%~x1

@echo TARGETDRIVE=!TARGETDRIVE!
@echo TARGETPATH=!TARGETPATH!
@echo TARGETNAME=!TARGATNAME!
@echo TARGETEXTENSION=!TARGETEXTENSION!

The output: 'B' is not recognized as an internal or external command, operable program or batch file.
'2' is not recognized as an internal or external command, operable program or batch file.
TARGETDRIVE=z:
TARGETPATH=\temp2\A
TARGETNAME=
TARGETEXTENSION=.mkv

1

There are 1 best solutions below

0
Magoo On

Just a few tips:

@ means "do not echo the command to the console". Command-echoing is controlled by echo on and echo off. Echo is ON by default, so the command @echo off means "Turn echo off, but do not echo this line to the console.`

Hence, once an @echo off is executed, there is no need to put @ before commands.

In your third echo statement, you have specified targAtname, which is undefined, hence the report shows nothing for that item.

! in place of % means "the value of the variable as it is at run-time, not at parse-time" and is really only applicable where a statement invokes a loop which changes the variable, like a for loop, but as aschipfl has pointed out, it comes in useful to overcome the special-characters effects in an echo statement.

Let's examine what batch does for one assignment:

@set TARGETPATH=%~p1

Batch substitutes the path part of the 1st parameter for %~p1 so the actual command executed is

@set TARGETPATH=A & B\

hence it assigns A to targetpath and then attempts to execute B\ hence the error message.

On a string assignment, it is standard practice on SO to use the syntax

set "TARGETPATH=%~p1"

The quotes protect against stray trailing spaces on the command line, and will also cure most problems with special characters.

BTW:

set target

will echo all variables whose names start target