Working on Windows CMD, is there a wildcard or other operator to find and replace "22" with "23" in all subfolders? I copied the folder structure from 2022 and want to rename all of the copied folders to be 2023.
I have the list of directories below.
Directory of c:\cmdTest
09/29/2022 10:46 AM <DIR> .
09/29/2022 10:46 AM <DIR> ..
09/29/2022 10:46 AM <DIR> 22
09/29/2022 10:30 AM <DIR> asdfsdf22
09/29/2022 10:30 AM <DIR> asdhfigh22
09/29/2022 10:30 AM <DIR> rheht22
09/29/2022 10:30 AM <DIR> sadfjksadfjk22
0 File(s) 0 bytes
7 Dir(s) 582,340,362,240 bytes free
and can change one at a time:
c:\cmdTest>ren 22 23
but cannot figure a way to change all of them at once. I have tried variations on the following and am stumped.
c:\cmdTest>ren *22 "23"
The syntax of the command is incorrect.
c:\cmdTest>ren ""%" "23"
The system cannot find the file specified.
c:\cmdTest>ren *22 23
The syntax of the command is incorrect.
CodePudding user response:
A batch file solution working only for folder names not containing one or more exclamation marks is:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir *22 /AD-L /B 2^>nul') do (
set "FolderName=%%I"
ren "!FolderName!" "!FolderName:~0,-1!3"
)
endlocal
The command FOR starts in background one more command process with option /c
to execute the command line specified within '
. So there is executed in background with Windows installed into C:\Windows
:
C:\Windows\System32\cmd.exe /c dir *22 /AD-L /B 2>nul
The command DIR searches
- in the current directory
- just for directories with ignoring junctions (hard links) and symbolic links because of option
/AD-L
(attribute directory and not link) - of which name is matched by the wildcard pattern
*22
- and outputs just the directory names without path because of option
/B
(bare format).
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul
. The redirection operator >
must be escaped with caret character ^
on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir
command line with using a separate command process started in background.
The output list of directory names is captured by cmd.exe
processing the batch file and is processed line by line after in background started cmd.exe
closed itself.
FOR with option /F
ignores always empty lines which do not occur here. There would be split up by default each line into substrings (tokens) using normal space and horizontal tab as delimiters and only the first space/tab delimited string would be assigned to the specified loop variable I
if the first substring does not start with a semicolon being the default end of line character resulting in ignoring the line too. The option delims=
defines an empty list of delimiters resulting in turning off the line splitting behavior. The option eol=|
defines the vertical bar as end of line character which no directory name can contain ever and so even directories with ;
at beginning of the name are processed by FOR. There could be used also eol=*
or eol=?
which are also not possible in a directory/file name.
The folder name is assigned to an environment variable which is referenced with delayed expansion on the command line to rename the folder by using as new folder name the current folder name with exception of last character 2
and appending character 3
as replacement for character 2
. It would be also possible to use "!FolderName:~0,-2!23"
to change the last two characters (year).
This batch file does not work if any directory has one or more !
in name because of permanently enabled delayed expansion resulting in command line set "FolderName=%%I"
being parsed a second time by cmd.exe
after replacing %%I
by the directory name currently assigned to the loop variable I
and interpreting the exclamation mark(s) in directory name as start/end of a delayed expanded environment variable reference instead of interpreting the exclamation mark(s) in directory name as literal character(s).
The solution for renaming correct also directories containing one or more exclamation marks is:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir *22 /AD-L /B 2^>nul') do (
set "FolderName=%%I"
setlocal EnableDelayedExpansion
ren "!FolderName!" "!FolderName:~0,-2!23"
endlocal
)
endlocal
That always working solution is slower because of using the commands SETLOCAL and ENDLOCAL within the loop. Read this answer for details about the commands SETLOCAL and ENDLOCAL. But a user will not notice the difference in time required to complete the folder renaming task for a small list of folders because of the processors are very fast nowadays.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
dir /?
echo /?
endlocal /?
for /?
ren /?
set /?
setlocal /?