Abner Mácola
Abner Mácola

Reputation: 101

shorten file path structure in windows

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

Answers (2)

Aacini
Aacini

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

Magoo
Magoo

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

Related Questions