Search code examples
batch-fileincludeparent-childdirectory-structurefile-rename

Batch rename of files including complete parent directory structure


I have quite an extensive folder structure with only one file in the deepest/last folder. File name: model.cgf

What I want is to have a command-line batch-file that renames all files, renaming them so they list their complete parent folder structure. And then copy all the files into one designated folder. The copied files would act as a catalog. So I know, when viewing a file, it's exact location in the folder structure. It would be awesome if the script could add only newer files when it is run again.

    Here is an example of the current file/folder structure:

    _All_Models
    |  |__Script.bat
    |
    |__Catalog
    |
    |__Models
       |
       |__SubFolder
       |  |__model.cfg 
       |  |
       |  |__SubFolder
       |  |  |__model.cfg
       |  |
       |  |__SubFolder
       |     |__SubFolder
       |     |  |__model.cfg
       |     |
       |     |__SubFolder
       |        |__SubFolder
       |           |__SubFolder
       |              |__model.cfg
       |
       |__etc.
       |  |__etc.
       |
       |__etc.

Here is an example of what I want:

    _All_Models
    |  |__Script.bat
    |
    |__Catalog
    |  |__SubFolder.cfg 
    |  |__SubFolder_SubFolder.cfg
    |  |__SubFolder_SubFolder_SubFolder.cfg
    |  |__SubFolder_SubFolder.cfg
    |  |__SubFolder_SubFolder_SubFolder_SubFolder.cfg
    |  |__etc.
    |  |__etc.
    |  |__etc.
    |
    |__Models
       |__etc.
       |__etc.
       |__etc.

What I can currently do is batch rename the file "model.cfg" into "parent-folder.cfg" and copy it into a designated folder. This will rename and consolidate all files, however I now am missing all previous parent folders and dont know where in the folder-structure the file is located.

I know very little about scripting, so I have done many searches to find something useful, but perhaps what I want is not possible. This is what I came-up with:

    CD Models

    REM Rename
    for /r %%D in (.) do (for /f "delims=" %%F in ('dir /b /A:-D "%%D"') do echo "%%D\%%F" "%%~nxD%%~xF")
    for /r %%F in (*) do (for /f "delims=" %%D in ("%%~dpF.") do ren "%%F" "%%~nxD%%~xF")

    REM Copy
    for /r "F:\All_Models\Models" %%i in (*.cgf) do copy "%%i" "F:\All_Models\Catalog"

My Catalog folder will now list all files named as: SubFolder.cgf (which is not detailed enough) The script also changes all filenames in the original folders, these should still be named: model.cgf

I'd appreciate any help on improving my script :)

Thanks!


Solution

  • I had already started creating a script before I saw Magoo's answer.

    My answer is almost the same, except:

    • All path computations are relative to the location of the script, so no need to set source or destination directories
    • I eliminate the leading path prefix differently. My method will fail if the leading path contains the = character (unlikely a problem)
    • I copy the files instead of move, which I believe is the intent of the OP
    • I hide the result of the copy and ECHO the resultant name of the copied file
    • I transfer all needed paths to variables and then toggle delayed expansion on and off so as to protect any ! that may be present in any of the paths.
    @echo off
    setlocal disableDelayedExpansion
    for /f "delims=" %%F in (
      'dir /b /s "%~dp0Models\Model.cfg"'
    ) do (
      set "old=%%F"
      set "new=%%~pF"
      setlocal enableDelayedExpansion
      set "new=!new:%~p0Models\=!"
      set "new=!new:\=_!"
      set "new=!new:~0,-1!.cfg"
      echo !new!
      copy "!old!" "%~dp0Catalog\!new!" >nul
      endlocal
    )
    

    I did not bother trying to only copy new files. Existing files in the catalog are simply overwritten. To properly determine if the file has changed you would need to use FC, which seems like a waste of time and effort.