Splitting a variable string containing poisonous characters into parts (filename/path/etc)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
koko
Posts: 38
Joined: 13 Oct 2016 00:40

Splitting a variable string containing poisonous characters into parts (filename/path/etc)

#1 Post by koko » 13 Oct 2016 01:19

Thanks to jeb's answer over on ss64.org I was able to finally get around the cmd.exe limitation of handling of ampersands (&) in input paths that contain no spaces (it only affects files drag-and-dropped onto batch scripts or sent via the Send to context menu).

However I need to be able to also split the input variable into parts: one variable for the filename portion, one for the directory, etc.

I've found that the test case batch code below works for simple filenames but when characters like single quotes, exclamation marks, and such are contained in the input variable the for loop (taken from this Stack Overflow page) fails to output the string properly.

Troublesome filenames (the last example features a Unicode colon not a regular one):

Code: Select all

! !§$%&()=`´'_;,.-#+´^ßöäüÖÄÜ°^^#
%!test2!
Test 'quotes'
test3 ꞉ blah


Test case batch:

Code: Select all

@echo off
setlocal EnableExtensions EnableDelayedExpansion


set "input=!cmdcmdline:~0,-1!"
set "input=!input:*" =!"
for %%a in ("!input!") do (
    set "folder=%%~dpa"
    set "name=%%~na"
)
echo !input!
echo !folder!
echo !name!

set /p prompt=

endlocal


Output of !name! variable above using the example filenames above (in order):

Code: Select all

.-#+'^ßöäüÖÄÜ°^^#
%
'quotes'
blah


The only reason I need to use the cmdcmdline variable in the first place is to handle the ampersand with no spaces path limitation, as otherwise I'd %~1 and %~n1 etc for the input variable (which works so long as delayed expansion is disabled at the time of storing the variable).

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Splitting a variable string containing poisonous characters into parts (filename/path/etc)

#2 Post by jeb » 13 Oct 2016 16:51

Hi koko,

I suppose that you can solve most of your problems by using FOR /F "delims=" %%a in ("!input!")
Only the exclamation marks needs to be handeled with the toggling delayed expansion technic.

koko
Posts: 38
Joined: 13 Oct 2016 00:40

Re: Splitting a variable string containing poisonous characters into parts (filename/path/etc)

#3 Post by koko » 13 Oct 2016 18:23

jeb wrote:Hi koko,

I suppose that you can solve most of your problems by using FOR /F "delims=" %%a in ("!input!")
Only the exclamation marks needs to be handeled with the toggling delayed expansion technic.


Perfect! Thanks a bunch, and for all the useful tips you and others here have shared :)

For anyone wondering this is what worked:

Code: Select all

@echo off
setlocal EnableExtensions EnableDelayedExpansion


set "input=!cmdcmdline:~0,-1!"
set "input=!input:*" =!"
for /f "delims=" %%a in ("!input!") do (
    setlocal EnableExtensions DisableDelayedExpansion
    set "folder=%%~dpa"
    set "name=%%~na"

)
setlocal EnableExtensions EnableDelayedExpansion

echo !input!
echo !folder!
echo !name!

set /p prompt=

endlocal

koko
Posts: 38
Joined: 13 Oct 2016 00:40

Re: Splitting a variable string containing poisonous characters into parts (filename/path/etc)

#4 Post by koko » 14 Oct 2016 01:33

Running into a bit of an issue with some related code. At the top of my script I allow for setting a variable in the .bat file itself to define a custom path for use later on in the script.

If the hard-coded variable contains percentage or exclamation marks they're stripped. Tried using similar for loops and enabling/disabling delayed expansion but didn't have any good results trying preserve the original variable.

Below is test case using a variant of the filenames listed previously (with Unicode characters removed for the Windows 1252 encoding) and instead used as variables set within the script itself.

Code: Select all

@echo off
setlocal EnableExtensions EnableDelayedExpansion

call :reformat "C:\ExamplePath\! !%&()='_;,.-#+^^#\" custompath1
call :reformat "C:\ExamplePath\%!test2!" custompath2
call :reformat "C:\ExamplePath\Test 'quotes'" custompath3

echo !custompath1!
echo !custompath2!
echo !custompath3!

set /p prompt=

:reformat
rem re-format path format for use later
set "reformat=%~1"
set "reformat=!reformat:"=!"
set "reformat=!reformat:/=\!"
set "reformat=!reformat!\"
set "reformat=!reformat:\\=\!"
set "%~2=!reformat!"
goto:eof

endlocal


Output when echo'd:

Code: Select all

C:\ExamplePath\&()='_;,.-#+^^#\
C:\ExamplePath\
C:\ExamplePath\Test 'quotes'\


Also tried to escape the percentages before they're stripped but that didn't work. Any suggestions?

Edit: I should also mention that normally the code for setting the custom path is just set custompath=, the call functions in the example above were just to illustrate the output of different names.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Splitting a variable string containing poisonous characters into parts (filename/path/etc)

#5 Post by jeb » 14 Oct 2016 04:07

It's possible but not in all cases. Exclamation marks needs three carets, but only when they are not quoted. for one percent sign you need four percent signs .

But at all you should avoid CALL with content by value, better put the content into a variable and then use by ref

Set var1=^! Test %%
Call :func var1


:func1
set arg=!%~1!

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Splitting a variable string containing poisonous characters into parts (filename/path/etc)

#6 Post by foxidrive » 14 Oct 2016 13:14

Just a personal viewpoint about having percent characters in filenames etc.

To me it is the most useless thing to try and handle in batch scripts and I use Total Commander to read an entire tree of files and then I use the multi-rename tool and replace every % with the word percent in one fell swoop.

That solves percent signs for me. hehe
TC can process many thousands of files and folders in the 'blink of an eye', and at least with a single operation.

koko
Posts: 38
Joined: 13 Oct 2016 00:40

Re: Splitting a variable string containing poisonous characters into parts (filename/path/etc)

#7 Post by koko » 14 Oct 2016 14:57

jeb wrote:It's possible but not in all cases. Exclamation marks needs three carets, but only when they are not quoted. for one percent sign you need four percent signs .

But at all you should avoid CALL with content by value, better put the content into a variable and then use by ref


So am I understanding it correctly that unless a hard-coded variable is manually escaped first the %/! characters can't be later seen or escaped via the script?

foxidrive wrote:Just a personal viewpoint about having percent characters in filenames etc.

To me it is the most useless thing to try and handle in batch scripts and I use Total Commander to read an entire tree of files and then I use the multi-rename tool and replace every % with the word percent in one fell swoop.


Yeah, not such a problem for me personally but rather those who may use the script. Not sure sure how keen people would be to manually escape entered paths :p Though if there's no workaround I may have to mention it.

Post Reply