I want to remove exclamation marks from file names on Windows 10/11 with a batch script.
I have a folder named "Input" in the same directory as the batch file, and i simply want to have the batch file look inside the Input folder for files with exclamation marks in the file name, and then remove any exclamation marks.
So for example:
this!_is!_an!_example!!!.txt
Would be renamed to:
this_is_an_example.txt
The below batch script will remove the character "Â". However, if i change it to "!" it will no longer work, probably because of enabledelayedexpansion
which has trouble with exclamation marks:
@echo off &setlocal
chcp 65001>nul
cd /d "C:\input"
for /f "delims=" %%a in ('dir /b /a-d *Â*.txt') do (
set "fname=%%~a"
setlocal enabledelayedexpansion
set "nname=!fname:Â=!"
ren "!fname!" "!nname!"
endlocal
)
pause
An exclamation mark is always interpreted as beginning/end of delayed expanded variable reference if there is enabled delayed variable expansion. There must be a subroutine used to rename files containing one or more !
with removing them from the file name with disabled delayed variable expansion.
@echo off & setlocal EnableExtensions DisableDelayedExpansion
%SystemRoot%\System32\chcp.com 65001 1>nul
cd /D "C:\input"
(for /F "eol=| delims=" %%I in ('dir "*!*" /A-D /B 2^>nul') do set "FileName=%%I" & call :RenameFile) & pause & exit /B
:RenameFile
ren "%FileName%" "%FileName:!=%" & goto :EOF
This batch file is designed for execution with a double click in Windows File Explorer or any other file manager resulting in the execution of %ComSpec% /C
and the fully qualified file name appended as one more argument for the executed Windows Command Processor which is executed to process the batch file and then close itself.
If the batch file should be used from within an opened command prompt window or should be called from another batch file, it would be better using following batch file:
@echo off & setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=*" %%G in ('%SystemRoot%\System32\chcp.com') do for %%H in (%%G) do set /A "CodePage=%%H" 2>nul
%SystemRoot%\System32\chcp.com 65001 1>nul
cd /D "C:\input"
(for /F "eol=| delims=" %%I in ('dir "*!*" /A-D /B 2^>nul') do set "FileName=%%I" & call :RenameFile) & goto EndBatch
:RenameFile
ren "%FileName%" "%FileName:!=%" & goto :EOF
:EndBatch
%SystemRoot%\System32\chcp.com %CodePage% 1>nul
endlocal
This version restores the initial environment before exiting including the code page in addition to current working directory, command extension state and delayed variable expansion state as restored also by the first batch file because of an implicit execution of endlocal
before cmd.exe
is finally exiting the processing of the batch file.
See the DosTips forum post [Info] Saving current codepage for an explanation of the second command line in second batch file.
See single line with multiple commands using Windows batch file for an explanation of the unconditional command operator &
used in both batch files multiple times for increasing the efficiency of batch file processing by reducing the number of times the batch file is opened, parsed and closed during its execution.