2

i want to rename one or more files using cmd. but a lot of this files have a special character. example:

DCIM_!01.jpeg
DCIM_&01.jpeg
DCIM_=01.jpeg

normally, we can use this value "^" to set a especial string as simple text. but when set enabledelayedexpansion the string don't is settable

set /p mystring=!

the users define string value: !, &, = and others...

the file name is defined by other variable "FOR" to search it in the folders

so string "File" value is "DCIM_!01.jpeg"

Command to change the file name:

setlocal enabledelayedexpansion
set new_filename=!file:^%mystring%=0!
echo !new_filename!

the results on prompt is:

:=0
file:=0
DCIM_!01.jpeg
DCIM_01.jpeg

I want to rewrite "!" to "0":

DCIM_001.jpeg

when i don't use a special string the command works for me

filmesson
  • 21
  • 3
  • Is there any reason not to just `disabledelayedexpansion`? That way, `ren "DCIM_%mystring:~0,1%01.jpeg" "DCIM_001.jpeg"` is perfectly safe even with characters like `&`. (cannot handle `"` but filenames cannot contain quotes anyways) – ScriptKidd Mar 31 '20 at 13:50

1 Answers1

1

Here is a quick demonstration code:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "TempDir=%TEMP%\%~n0"
if exist "%TempDir%\" goto CreateFiles
md "%TempDir%" && goto CreateFiles
echo Failed to create temporary directory:
echo/
echo "%TempDir%"
echo/
pause
rem The command endlocal is executed implicit by cmd.
exit /B

:CreateFiles
pushd "%TempDir%"
echo DCIM_!01.jpeg>"%TempDir%\DCIM_!01.jpeg"
echo DCIM_^&02.jpeg>"%TempDir%\DCIM_&02.jpeg"
echo DCIM_=03.jpeg>"%TempDir%\DCIM_=03.jpeg"
echo DCIM_%%04.jpeg>"%TempDir%\DCIM_%%04.jpeg"
echo DCIM_)05.jpeg>"%TempDir%\DCIM_)05.jpeg"

:UserPrompt
set "MyString="
set /P "SearchString=String to replace: "
rem Has the user not entered a string?
if not defined SearchString goto UserPrompt
rem Remove all double quotes.
set "SearchString=%SearchString:"=%"
rem Is there no search string left?
if not defined SearchString goto UserPrompt
rem Replace all exclamation marks by vertical bars.
set "SearchString=%SearchString:!=|%"
echo/

for /F "eol=| delims=" %%I in ('dir "*.jpeg" /A-D /B 2^>nul') do (
    set "RealName=%%I"
    set "FileName=%%I"
    rem Replace in file name all exclamation marks by vertical bars.
    call set "FileName=%%FileName:!=|%%"
    setlocal EnableDelayedExpansion
    set "NewName=!FileName:%SearchString%=0!"
    if not "!NewName!" == "!FileName!" echo ren "!RealName!" "!NewName!"
    endlocal
)

echo/
%SystemRoot%\System32\choice.exe /C NY /N /M "Run once more (Y/N):"
if errorlevel 2 goto UserPrompt

popd
rd /Q /S "%TempDir%"
endlocal

You can see that the demo code does not work for search strings containing =. There must be special code used for replacing equal signs or a different script interpreter is used like PowerShell.
See also: How to replace “=” (equal signs) and a string variable?

The solution for exclamation marks is replacing in search string each ! by | and do the same for the current file name before enabling delayed environment variable expansion. A file name cannot contain a vertical bar as described by Microsoft on documentation page Naming Files, Paths, and Namespaces. So it is safe to replace all ! by | in a file name before doing the string substitution with enabled delayed expansion.

The replacement of ! by | in the FOR loop must be done by referencing the environment variable FileName with %%. The reason is that the command line

call set "FileName=%%FileName:!=|%%"

is processed by cmd.exe before execution of command FOR to

call set "FileName=%FileName:!=|%"

The command CALL is used to force a second parsing and processing of this command line by cmd.exe on each iteration of the loop to really do the character replacement on current string value assigned to environment variable FileName.

See also:

Then delayed expansion can be enabled to do the string replacement on already slightly modified file name and run the command REN on file name really modified by the string replacement with real name of current file and new file name. Read this answer for details about the commands SETLOCAL and ENDLOCAL.

The demonstration code does not really run the command REN, it just outputs how REN would be executed on removing command ECHO.

Mofi
  • 46,139
  • 17
  • 80
  • 143
  • thank you very much. with your example i can create my batch file working full. thanks so. i left this example of my batch to you see, but idon't understand as you about this scripts. https://filebin.net/vh355pwy1uau3xpf/BatchExample_working_test.bat?t=452p3tp6 – filmesson Apr 01 '20 at 15:19