I have a bunch of files that are in the following format
filename-!#.ext
where # is an incrementing number to prevent collisions. I would like to just remove the ! from the filename so it reads as
filename-#.ext
It seems like I could do this with the ren command and wildcards but having a hard time getting it to work. I tried running this:
ren *!?.ext *?.ext
My thought is the * should match the filename- part, then !, then the ? for the numeric. However, the resulting file is named this:
filename-!#.ext.ext
and I can't quite figure out why.
The filename part can be dynamic, but won't contain any !'s. Any ideas?
I think you'll have to resort to a small batch file for this:
@echo off
setlocal
for %%a in (*!*.ext) do call :remove "%%~a"
goto :eof
:remove
set "FROM=%~1"
set "TO=%FROM:!=%"
ren "%FROM%" "%TO%"
goto :eof
The above will – for all files containing an exclamation mark and extension ext
– call the remove
function. This takes the original name (FROM
) and determines the new name (TO
) by using the %var:find=replace%
syntax to remove any exclamation mark (replaces it with an empty string).
Notes
You cannot use find/replace with either %%a
or %0
type variables, so you have to assign it to a named variable first.
I originally tried doing this "inline" with the for
statement (e.g. for ... (
ending )
) but to do that, you would have to enable delayed-expansion (because you would need to access a named variable in a loop). However, delayed-expansion uses !
(instead of %
) to reference variables and this got in the way of the !
we were trying to remove. There may be a way of doing this, but I haven't found it. Using call
will be slightly slower, but not significantly unless you've got thousands of files.
You don't really need to create TO
(you could perform the replacement on the ren
command-line) but I used it for clarity.
This will work for all files with an exclamation mark: it doesn't check the bit after is numeric.
I think it is not a good idea to let rename
select the files, but instead do it with a for
-loop and then execute the rename for every file:
for %%F in (*!*) do (
set "nxF=%%~nxF"
call ren "%%nxF%%" "%%nxF:!=%%"
)
You really have to use call
here instead of delayedExpansion
, because delayedExpansion
would destroy the rename-arguments (because they contain !
)
Based upon your provided information and just for the sake of offering something a little different, you could let delayed expansion do the work for you, (as it will remove the unwanted exclamation mark for you).!
@For %%A In ("*-!?.ext") Do @Set "_=%%A" & SetLocal EnableDelayedExpansion & Ren "!_!" "%%A" & EndLocal
You could probably also do it with a nested for loop:
@For %%A In ("*-!?.ext") Do @For /F "Tokens=1*Delims=!" %%B In ("%%A") Do @Ren "%%A" "%%B%%C"
…and from the Command Prompt:
For %A In ("*-!?.ext") Do @For /F "Tokens=1*Delims=!" %B In ("%A") Do @Ren "%A" "%B%C"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With