Gauthier
Gauthier

Reputation: 41945

cmd string replacement of special character

I am trying to replace ~ with %HOME% in a batch script. This is what I have so far:

@echo off
setlocal enabledelayedexpansion
set str=%*
set replacement=%HOME%
set str=%str:~=!replacement!%
echo %str%

This does not work as I expect, presumably because I need to escape the tilde ~ in some way.

When I escape with ^, str is unchanged. Without escape, str is the string str:~=<my_home_path>.

How can I change "~/work/my_folder" into "C:/Users/login/work/my_folder"?

Upvotes: 4

Views: 6963

Answers (4)

Todd
Todd

Reputation: 1

    @ECHO OFF
    CLS
    SET OldStr=~\work\my_folder
    SET NewStr=
    SET Replacement=C:\Users\login\work\my_folder
    CALL :ReplaceHome "%OldStr%"
    ECHO %NewStr%
    EXIT /b %ERRORLEVEL%

    :ReplaceHome
    IF "%~1"=="" EXIT /B %ERRORLEVEL%
    SET TempStr=%~1
    IF "%TempStr:~0,1%"=="~" SET TempStr=%Replacement%%TempStr:~1%
    SET NewStr=%NewStr%%TempStr:~0,1%
    CALL :ReplaceHome "%TempStr:~1%"
    EXIT /B %ERRORLEVEL%

Upvotes: 0

rojo
rojo

Reputation: 24466

I think you're pretty close already except for a couple of minor problems.

Firstly, there's probably no environment variable in Windows for %home% -- at least not on my system, anyway. I think the variable you're looking for is %userprofile%. ss64.com has an excellent list and description of Windows environment variables.

The other problem is that you're delaying expansion in the wrong order. Try changing your penultimate line to set str=!str:~=%userprofile%! so that the inner variable expands before the outer. Translating forward slashes to backward might not be a bad idea, either.

@echo off
setlocal enabledelayedexpansion
set str=%*
set "str=!str: ~= %userprofile%!"
set "str=!str:*~=%userprofile%!"
set "str=%str:\=/%"
echo %str%

Example output:

C:\Users\me\Desktop>test ~/.bash_profile
C:/Users/me/.bash_profile

C:\Users\me\Desktop>test arg1 arg2 ~/.bash_profile
arg1 arg2 C:/Users/me/.bash_profile

Upvotes: 1

Endoro
Endoro

Reputation: 37569

Or a bit more complex:

@echo off &setlocal enabledelayedexpansion
set "str=~/work/my_folder -param one ~ two:~"
set "replacement=C:/Users/login"
call :strlen str len
set /a len-=1
for /l %%i in (0,1,%len%) do if "!str:~%%i,1!"=="~" (set "new=!new!%replacement%") else set "new=!new!!str:~%%i,1!"
echo %new%
goto :eof

:strlen
:: list string length up to 8189 (and reports 8189 for any string longer than 8189)
:: function from http://ss64.org/viewtopic.php?pid=6478#p6478
(   setlocal enabledelayedexpansion & set /a "}=0"
    if "%~1" neq "" if defined %~1 (
        for %%# in (4096 2048 1024 512 256 128 64 32 16) do (
            if "!%~1:~%%#,1!" neq "" set "%~1=!%~1:~%%#!" & set /a "}+=%%#"
        )
        set "%~1=!%~1!0FEDCBA9876543211" & set /a "}+=0x!%~1:~32,1!!%~1:~16,1!"
    )
)
endlocal & set /a "%~2=%}%" & exit /b
endlocal

Output:

C:/Users/login/work/my_folder -param one C:/Users/login two:C:/Users/login

This doesn't work with exclamation marks.

Upvotes: 3

Endoro
Endoro

Reputation: 37569

If the ~ is always the first character, you can use somewhat like this:

@echo off &setlocal enabledelayedexpansion
set "str=|~/work/my_folder"
set "replacement=C:/Users/login"
set str=%str:|~=!replacement!%
echo %str%

Upvotes: 3

Related Questions