Tharaka Wijerama
Tharaka Wijerama

Reputation: 83

How do I escape tilde (~) in batch file on replacing it with a different character?

The script can replace certain characters to specified character in file names, but is not working for tilde ~.

Below two parts are working perfectly.

@echo off
setlocal enabledelayedexpansion
for %%a in (*_*) do (
    set file=%%a
    ren "!file!" "!file:_=A!"
)
for %%a in (*-*) do (
    set file=%%a
    ren "!file!" "!file:-=B!"
)

But this part is not working.

for %%a in (*~*) do (
    set file=%%a
    ren "!file!" "!file:~=C!"
)

Why is replacement of ~ not working and how to solve that?

Upvotes: 2

Views: 1639

Answers (1)

aschipfl
aschipfl

Reputation: 34949

You are using sub-string substitution syntax (like !file:search=replac!), which does not allow a search string to begin with ~, because then it would be confused with sub-string expansion syntax (like !file:~pos,len!).

What you can do is using for /F to split your file names at the ~ character:

for /F "tokens=1* delims=~ eol=~" %%I in ('dir /B /A:-D "*~*"') do (
    if not "%%J" == "" ren "%%I~%%J" "%%IC%%J"
)

This works only if there is a single ~ character and such is not at the first position.

If there is more than one ~ character and at any position, it becomes a bit more complex:

@echo off
for /F "delims= eol=|" %%F in ('dir /B /A:-D "*~*" ^| find "~"') do (
    set "FILE=%%F" & set "EXT=%%~xF"
    call :SUB NAME "%%~nF" C
    setlocal EnableDelayedExpansion
    ren "!FILE!" "!NAME!!EXT!"
    endlocal
)
exit /B

:SUB
    set "#RET=%~1"
    set "STR=%~2"
    set "CHR=%~3"
    set "LEFT=" & set "REST="
    if not defined STR goto :NEXT
:LOOP
    set "REST=%STR:*~=%"
    if "%REST%" == "%STR%" goto :NEXT
    for /F "delims=~ eol=~" %%E in ("_%STR%") do set "LEFT=%%E"
    set "STR=%LEFT:~1%%CHR%%REST%"
    goto :LOOP
:NEXT
    set "%#RET%=%STR%"
    exit /B

The sub-routine :SUB splits the file name string at every ~ in a loop and rebuilds it by replacing ~ with the specified character.

The filter | find "~" (as well as the if not "%%J" == "" condition in the first approach) are needed because dir matches also short file names, which usually contain a ~ character. If such 8.3 file names are disabled on your system, these additional code portions might be removed (although they do not harm).

Upvotes: 5

Related Questions