Reputation: 101
I have a structure of files inside folders with really large names. The folders have this structure: "C:\images\Calc-Test_P_00038_LEFT_CC\08-29-2017-DDSM-NA-96009\1ooP00image" and inside this folder there is a single .dcm file. There are 600 files inside this structure, each file inside one of those folders, and the files sometimes have the same name (file.dcm). I need to rename this whole folder structure to have shorten names like "C:\images\1\1\1\file.dcm", "C:\images\2\2\2\file.dcm" and so on, this way I can upload the whole structure to the repository where I will work with these images. I have tried this bat script without success, because I cannot use python on this computer. Any help with the code or any alternative would be welcome.
@echo off
setlocal enabledelayedexpansion
set "root_dir=C:\images"
set /A counter=1
for /f "delims=" %%D in ('dir "%root_dir%" /ad /b /s /o-n') do (
set "folder_path=%%D"
set "folder_name=%%~nxD"
set "contains_dcm_file=0"
for %%F in ("%%D\*.dcm") do (
set "contains_dcm_file=1"
goto :skip_renaming
)
set "parent_path=%%~dpD"
set "new_name=!counter!"
if not "!folder_name!"=="!new_name!" (
ren "!folder_path!" "!new_name!"
)
set /A counter+=1
:skip_renaming
)
echo Done.
pause
Upvotes: -1
Views: 73
Reputation: 67186
Your description is not clear enough... However, if you want to just rename folders, then this simple recursive process do it no matter the number nor level of the nested folders:
@echo off
cd C:\images
call :treeProcess
goto :eof
:treeProcess
setlocal EnableDelayedExpansion
set "counter=0"
for /F "delims=" %%D in ('dir /AD /B') do (
cd "%%D"
call :treeProcess
cd ..
set /A counter+=1
move "%%D" "!counter!"
)
exit /b
Further details at this answer
If you want to rename only the folders that contains a .dcm file, then just enclose the set /A
and move
commands in an if exist "%%D\*.dcm" (
command.
NOTE: Remember that ren
command just rename files. In order to rename folders, you must use move
command.
Upvotes: 0
Reputation: 79957
for /f "delims=" %%D in ('dir "%root_dir%" /ad /b /s /o-n') do (
set "folder_path=%%D"
set "folder_name=%%~nxD"
SET "contains_dcm_file="
for %%F in ("%%D\*.dcm") do (
set "contains_dcm_file=1"
)
IF NOT DEFINED contains_dcm_file (
set "parent_path=%%~dpD"
set "new_name=!counter!"
if not "!folder_name!"=="!new_name!" (
ren "!folder_path!" "!new_name!"
)
)
set /A counter+=1
)
Changes :
contains_dcm_file
now a Boolean - see Using Boolean
contains_dcm_file
is initialised to nothing on each loop, then set to something if the .dcm
file is found.
Then test whether contains_dcm_file
is defined,meaning a .dcm
file was found, and do actions if NOT.
I've not tested this, so I'm relying on your original code doing what you want.
For testing, I'd use ECHO ren
to verify instead of performing unwanted renames. Just remove the echo
after testing to activate the rename.
I prefer to avoid ADFNPSTXZ (in either case) as metavariables (loop-control variables) as ADFNPSTXZ are also metavariable-modifiers which can lead to difficult-to-find bugs (See for/f
from the prompt for documentation) The documentation nominates only alphabetic characters. Some symbols appear to work, but are undocumented.
Upvotes: 1