I have a lot of files in this format:
D:\images\AAA_BBB\image\whatever1.jpg
D:\images\AAA_BBB\image\whatever2.jpg
D:\images\FFF_EEE_CCC\image\asdf1.jpg
D:\images\FFF_EEE_CCC\image\asdf2.jpg
D:\images\WWW_XXX_YYY_ZZZ\image\someimage1.jpg
D:\images\WWW_XXX_YYY_ZZZ\image\someimage2.jpg
I'd like to move and rename these files using a substring of the absolute file path and remove the original files so that the results will look something like the below, starting with 0
.
D:\images\AAA\AAA_0.jpg
D:\images\AAA\AAA_1.jpg
D:\images\EEE\EEE_0.jpg
D:\images\EEE\EEE_1.jpg
D:\images\YYY\YYY_0.jpg
D:\images\YYY\YYY_1.jpg
Note that the number of tokens in the folder with the underscores can be any length.
The following attempt, would only give me the 2nd token starting from the front. Using "Tokens=-2" to get the 2nd last token wouldn't output anything.
@echo off & setlocal EnableDelayedExpansion
PushD "D:\images" || Exit /B
For /F "EOL=? Delims=" %%G In ('Dir /A:D /B 2^>NUL
^| %SystemRoot%\System32\findstr.exe /I /R "^[^_][^_]*_[^_][^_]*_[^_][^_]*_"'
) Do For /F "Tokens=2 EOL=? Delims=_" %%H In ("%%G") Do (
Set "i=-1"
For /F "EOL=? Delims=" %%I In ('Dir "%%G\image" /A:-D /B') Do (
Set /A i += 1
SetLocal EnableDelayedExpansion
Ren "%%G\image\%%I" "%%H_!i!%%~xI" && (
If Not Exist "%%H\." MD "%%H"
Move /Y "%%G\image\%%H_!i!%%~xI" "%%H"
)
EndLocal
)
)
PopD
Then I used different logic by trying two for
loops to get the last token, and then the 2nd last token, but it didn't work.
@echo off & setlocal EnableDelayedExpansion
PushD "D:\images" || Exit /B
For /F "EOL=? Delims=" %%G In ('Dir /A:D /B 2^>NUL
^| %SystemRoot%\System32\findstr.exe /I /R "^[^_][^_]*_[^_][^_]*_[^_][^_]*_"'
) Do (
Set "dirName=%%G"
Set "lastSegment="
For %%H In ("!dirName:_=" "!") Do (
Set "secondLastSegment=!lastSegment!"
Set "lastSegment=%%~H"
)
Set "segment=%%~xG"
Set "i=-1"
For /F "EOL=? Delims=" %%I In ('Dir "%%G\image" /A:-D /B') Do (
Set /A i += 1
SetLocal EnableDelayedExpansion
Ren "%%G\image\%%I" "!secondLastSegment!_!i!!segment!" && (
If Not Exist "!secondLastSegment!\." MD "!secondLastSegment!"
Move /Y "%%G\image\!secondLastSegment!_!i!!segment!" "!secondLastSegment!"
)
EndLocal
)
)
PopD
This should work:
@echo off
setlocal EnableDelayedExpansion
pushd "D:\images" || exit /B
for /D %%d in (*_*) do (
set "oldName=%%d"
for %%b in (".!oldName:_=.!") do for %%c in ("%%~Nb") do set "newName=%%~Xc"
set "newName=!newName:~1!"
md "!newName!"
set "i=-1"
for %%f in ("%%d\image\*.jpg") do (
set /A i+=1
move "%%~f" "!newName!\!newName!_!i!%%~Xf"
)
)
Your examples have a lot of unneeded or redundant code...
for /F
command when you just want to process files or folders; plain for
or for /D
are simpler and works faster than for /F
.for /D %%d in (*_*) do
command process all folders with at least one underscore; I don't see why you use a findstr
with a complicated regex...~Name
and ~eXtension
FOR command parameter modifiers.