Renaming Folder Structure in Batch

2019-08-09 09:51发布

问题:

)

In order to make the company (where I'm working) operate more organized and efficiently we've created an approved folder structure for new projects.

New projects and Live projects reside on a file server and are at the same level as each other. (Live projects have made it through planning, new projects sometimes only go as far as planning)

The project folder structure can be a meticulous to create each time we start a new project, therefore I made a windows batch file to create it. You can find it here: http://pastebin.com/mnSu5vnk This part works well!

The folder structure is:

F:\New Job\Project Name\Project Correspondence

F:\New Job\Project Name\Project Directory

F:\New Job\Project Name\Project Drawings

F:\New Job\Project Name\Project Images

F:\New Job\Project Name\Project Correspondence\Arboriculturalist

F:\New Job\Project Name\Project Correspondence\CGI

F:\New Job\Project Name\Project Correspondence\Client

F:\New Job\Project Name\Project Correspondence\Measured Survey

F:\New Job\Project Name\Project Correspondence\Planning

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)

F:\New Job\Project Name\Project Correspondence\Client\Appointments

F:\New Job\Project Name\Project Correspondence\Client\Fees

F:\New Job\Project Name\Project Correspondence\Planning\LA Planning

F:\New Job\Project Name\Project Correspondence\Planning\Planning Consultants

F:\New Job\Project Name\Project Correspondence\Planning\LA Planning\Planning Application

F:\New Job\Project Name\Project Correspondence\Planning\LA Planning\Pre Application

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)\Arboriculturalist

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)\Contract Administrator

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)\Contractor

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)\LA Building Control

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)\M&E Consultants

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)\Structural Engineer

F:\New Job\Project Name\Project Correspondence\Post Planning Folders (Drop in as and when)\Tender, Specification

F:\New Job\Project Name\Project Drawings\CD Series (Construction Details)

F:\New Job\Project Name\Project Drawings\Drawing Register

F:\New Job\Project Name\Project Drawings\EW Series (External Works)

F:\New Job\Project Name\Project Drawings\Outgoing Drawings

F:\New Job\Project Name\Project Drawings\P Series (Planning)

F:\New Job\Project Name\Project Drawings\RL Drawings (Room Layouts)

F:\New Job\Project Name\Project Drawings\SK Series (Sketch Design)

F:\New Job\Project Name\Project Drawings\X Series (Existing)

F:\New Job\Project Name\Project Drawings\Outgoing Drawings\DWG FILES

F:\New Job\Project Name\Project Drawings\Outgoing Drawings\PDF FILES

The problem is that some new projects never make it to "Live" status; however, those that do get allocated a project number and consequently need prefixing each sub-folder with the project number. The reason for prefixing each sub-folder with the project number is owing to "people" accidentally dragging/copying/moving them off into the another project which can make things very confusing!

An additional problem is that some of the "new projects" have been sitting there for a while (1 year+) and have no folder structure to them, therefore I need to make a batch file that detects if the "new project" has the approved folder structure or not, and rename as appropriate.

This is what I currently have but I believe my methodology is all wrong.

@Echo off
:start
set /P ProjNo=Project Number:
set /P ProjAd=Project Address:
cls

Echo New Project Name?
Echo Project Number=%ProjNo%
Echo Project Address= %ProjAd%

set /p proceed=Is this correct? [Y/N]
if /i {%proceed%}=={y} (goto :yes)
if /i {%proceed%}=={yes} (goto :yes)
if /i {%proceed%}=={n} (goto :no)
if /i {%proceed%}=={no} (goto :no)

:no
cls
goto :start

:yes
set "currentpath=%cd%"
set "projfolder=%ProjNo%-%ProjAd%"

:: check if 000-Project Address doesn't exists
echo Does the Project folder exist %currentpath%\%ProjNo%-%ProjAd%?
If NOT exist "%currentpath%\%ProjNo%-%ProjAd%\" 
    (
    echo the folder does NOT exist
        ::check if project folder name doesn't existing
        if NOT exist "%currentpath%\%ProjAd%\" 
        (
            :: rename the folder to 000-Project Address
            echo Renaming Project Folder
            ren "%ProjAd%" "%ProjNo%-%ProjAd%"

            call:TopLevel
        )
        ::if project address name DOES exist
        else 
        (       
            ::enter the folder and check the structure.
            echo Project Folder doesn't need renaming
            call:TopLevel
        )
    )
::-----------------------------------------------------
::      if "000-Project Address" DOES exist
::-----------------------------------------------------

    else 
    (
        Echo There is no need to run this script!
        goto:eof
    )
  )
  ::-----------------------------------------------------
  ::    Recurse Top level
  ::
  ::   If all the "Recommended" directory names exist 
  ::   rename all sub-directories too!
  ::   Else create them all!
  ::-----------------------------------------------------
    :TopLevel 

    CD projfolder
        ::check if there's a project correspondence 
        IF exist "Project Correspondence" 
        (   
            ren "Project Correspondence" "%ProjNo%-Project Correspondence"
            ::rename the child folders
            cd "%ProjNo%-Project Correspondence"
            for /f "tokens=*" %G in ('dir /b /a:d "*"') do ren "%G" "%ProjNo%-%G"
            cd "%ProjNo%-client"
            for /f "tokens=*" %G in ('dir /b /a:d "*"') do ren "%G" "%ProjNo%-%G"
            cd ..\planning\


        )
        else 
        (
            mkdir "%ProjNo%-Project Correspondence"
            callto: 
            ::function makeProjCorrespondence
            call:makeProjCorrespondence %ProjNo% 
        )
        :: check if there's a project directory
        IF exist "Project Directory" 
        (
            ren "Project Directory" "%ProjNo%-Project Directory"
        )
        else 
        (
            mkdir "%ProjNo%-Project Directory"
        )
        if exist "Project Drawings" 
        (
            ren "Project Drawings" "%ProjNo%-Project Drawings"
            ::go to project drawings function
        )
        goto:eof

  :makeProjCorrespondence
  cd "%ProjNo%-Project Correspondence"
    mkdir "%ProjNo%-Planning"
    mkdir "%ProjNo%-Arboriculturalist"
    mkdir "%ProjNo%-CGI"
    mkdir "%ProjNo%-Client"
    mkdir "%ProjNo%-Measured Survey"
    mkdir "%ProjNo%-Post Planning Folders (Drop in as and when)"

    ::Make folders under Planning
    cd "%ProjNo%-Planning"
        mkdir "%ProjNo%-LA Planning"
        mkdir "%ProjNo%-Planning Consultants"
    cd "..\"

    ::Make folders in Client
    cd "%ProjNo%-Client"
        mkdir "%ProjNo%-Appointments"
        mkdir "%ProjNo%-Fees"
    cd "..\"

    ::make Post Planning folders
    cd "%ProjNo%-Post Planning Folders (Drop in as and when)"
        mkdir "%ProjNo%-Arboriculturalist"
        mkdir "%ProjNo%-Contract Administrator"
        mkdir "%ProjNo%-Contractor"
        mkdir "%ProjNo%-LA Building Control"
        mkdir "%ProjNo%-M&E Consultants"
        mkdir "%ProjNo%-Structural Engineer"
        mkdir "%ProjNo%-Tender, Specification"
    cd "..\..\"
    goto:TopLevel

Tips and advice would be much appreciated!

Many thanks

回答1:

This is designed to recurse through a folder tree say called c:\database\project daredevil and add 001- to the front of each folder name in the tree.

@echo off
set "num=001-"
for /d /r "c:\database\project daredevil" %%a in (*) do ren "%%a" "%num%%%~nxa"

This code will report which folders are missing, and will create the missing folders.
You can make num equal to nothing to create a fresh set of folders.

EDIT2:

@echo off
set "num=001-"
set "project=c:\database\project daredevil"

for %%a in (
"Project Correspondence"
"Project Directory"
"Project Drawings"
"Project Images"
"Project Correspondence\%num%Arboriculturalist"
"Project Correspondence\%num%CGI"
"Project Correspondence\%num%Client"
"Project Correspondence\%num%Measured Survey"
"Project Correspondence\%num%Planning"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)"
"Project Correspondence\%num%Client\%num%Appointments"
"Project Correspondence\%num%Client\%num%Fees"
"Project Correspondence\%num%Planning\%num%LA Planning"
"Project Correspondence\%num%Planning\%num%Planning Consultants"
"Project Correspondence\%num%Planning\%num%LA Planning\%num%Planning Application"
"Project Correspondence\%num%Planning\%num%LA Planning\%num%Pre Application"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)\%num%Arboriculturalist"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)\%num%Contract Administrator"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)\%num%Contractor"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)\%num%LA Building Control"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)\%num%M&E Consultants"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)\%num%Structural Engineer"
"Project Correspondence\%num%Post Planning Folders (Drop in as and when)\%num%Tender, Specification"
"Project Drawings\%num%CD Series (Construction Details)"
"Project Drawings\%num%Drawing Register"
"Project Drawings\%num%EW Series (External Works)"
"Project Drawings\%num%Outgoing Drawings"
"Project Drawings\%num%P Series (Planning)"
"Project Drawings\%num%RL Drawings (Room Layouts)"
"Project Drawings\%num%SK Series (Sketch Design)"
"Project Drawings\%num%X Series (Existing)"
"Project Drawings\%num%Outgoing Drawings\%num%DWG FILES"
"Project Drawings\%num%Outgoing Drawings\%num%PDF FILES"
) do (
   if not exist "%project%\%num%%%~a\" (
      echo "%project%\%num%%%~a\" is missing
      md "%project%\%num%%%~a\" 
   )
)
pause


回答2:

The final code is this for those wanting to know how to do it!

Much thanks to @foxidrive for help with this problem! :)

@Echo off
:start
set /P ProjNo=Project Number:
set /P ProjName=Project Name:
::usually we clear screen but for the time being... let's not
::cls

Echo Please Confirm Project Details?
Echo Project Number=%ProjNo%
Echo Project Address= %ProjName%

set /p proceed=Is this correct? [Y/N]
if /i {%proceed%}=={y} (goto :yes)
if /i {%proceed%}=={yes} (goto :yes)
if /i {%proceed%}=={n} (goto :no)
if /i {%proceed%}=={no} (goto :no)

:no
cls
goto :start

:yes

set "project=%cd%\%ProjName%"

for %%a in (
"Project Correspondence"
"Project Directory"
"Project Drawings"
"Project Images"
"Project Correspondence\Arboriculturalist"
"Project Correspondence\CGI"
"Project Correspondence\Client"
"Project Correspondence\Measured Survey"
"Project Correspondence\Planning"
"Project Correspondence\Post Planning Folders (Drop in as and when)"
"Project Correspondence\Client\Appointments"
"Project Correspondence\Client\Fees"
"Project Correspondence\Planning\LA Planning"
"Project Correspondence\Planning\Planning Consultants"
"Project Correspondence\Planning\LA Planning\Planning Application"
"Project Correspondence\Planning\LA Planning\Pre Application"
"Project Correspondence\Post Planning Folders (Drop in as and when)\Arboriculturalist"
"Project Correspondence\Post Planning Folders (Drop in as and when)\Contract Administrator"
"Project Correspondence\Post Planning Folders (Drop in as and when)\Contractor"
"Project Correspondence\Post Planning Folders (Drop in as and when)\LA Building Control"
"Project Correspondence\Post Planning Folders (Drop in as and when)\M&E Consultants"
"Project Correspondence\Post Planning Folders (Drop in as and when)\Structural Engineer"
"Project Correspondence\Post Planning Folders (Drop in as and when)\Tender, Specification"
"Project Drawings\CD Series (Construction Details)"
"Project Drawings\Drawing Register"
"Project Drawings\EW Series (External Works)"
"Project Drawings\Outgoing Drawings"
"Project Drawings\P Series (Planning)"
"Project Drawings\RL Drawings (Room Layouts)"
"Project Drawings\SK Series (Sketch Design)"
"Project Drawings\X Series (Existing)"
"Project Drawings\Outgoing Drawings\DWG FILES"
"Project Drawings\Outgoing Drawings\PDF FILES"
) do (
   if not exist "%project%\%%~a\" (
      echo "%project%\%%~a\" is missing
      md "%project%\%%~a\"
   )
)
::Now add the prefixing number!
for /d /r "%project%" %%a in (*) do ren "%%a" "%ProjNo%-%%~nxa"

ren "%ProjName%" "%ProjNo%-%ProjName%"
Echo Project %ProjName folder has now been renamed to %ProjNo%-%ProjName%
pause


回答3:

I'm a little disappointed that my suggestion about a template directory was not taken up, so here's another solution. Note that a change to the structure required (yet more directories, etc.) would be automagic - no need to change the batch...

@ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir\project template"
SET "destdir=c:\destdir"

SET "num=001-"
SET "project=project daredevil"

FOR /f "delims=" %%a IN (
 ' dir /s/b /ad "%sourcedir%" '
) DO (
 CALL :makecopy "%%a"
)

GOTO :EOF
:makecopy
SET "srce=%~1"
CALL SET "dest=%%srce:%sourcedir%\=%destdir%\%%
CALL SET "dest=%%dest:#=%num%%%
ECHO MD "%dest%"
IF NOT EXIST "%srce%\*" GOTO :eof
FOR %%i IN ("%srce%\*") DO (
IF NOT EXIST "%dest%\%%~nxi" ECHO COPY /b "%%i" "%dest%\%%~nxi"
)
GOTO :EOF

(Noting that MDs and COPYs are merely ECHOed for testing - remove the ECHO to actute

One advantage here is that by setting up a structure below %sourcedir%, WHEN the structure is changed, all you need do is to modify the template.

Note that any # in the directoryname is replaced by %num% on execution, so it's easy to select if and where the injection of the project number takes place.

Another advantage is that a common form - like a blank spreadsheet or doc file containing the disclaimers, forms, legal folderol - could also be placed in the template structure. For instance, Where a submission requires a series of steps, you could have a simple spreadsheet nominating the steps that need to be taken, with columns to record who, when and document reference numbers.


For clarification, extension and exemplification, with num set to 001-

@ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir\project template"
SET "destdir=c:\destdir"

SET "num=001-"
SET "project=project daredevil"

FOR /f "delims=" %%a IN (
 ' dir /s/b /ad "%sourcedir%" '
) DO (
 CALL :makecopy "%%a"
)

GOTO :EOF
:makecopy
SET "srce=%~1"
CALL SET "dest=%%srce:%sourcedir%\=%destdir%\%%
CALL SET "dest=%%dest:#=%num%%%
ECHO MD "%dest%"
IF NOT EXIST "%srce%\*" GOTO :eof
FOR %%i IN ("%srce%\*") DO (
 SET fname=%%~nxi
 CALL :subsfn
)
GOTO :EOF
:subsfn
CALL SET "mfname=%%fname:#=%num%%%
IF NOT EXIST "%dest%\%mfname%" ECHO COPY /b "%sourcedir%\%fname%" "%dest%\%mfname%"
GOTO :EOF

Dir structure:

c:\sourcedir\project template\some directory
c:\sourcedir\project template\some#directory
c:\sourcedir\project template\some#directory\a filename.txt
c:\sourcedir\project template\some#directory\a#filename.txt

Run result:

MD "c:\destdir\some directory"
MD "c:\destdir\some001-directory"
COPY /b "c:\sourcedir\project template\a filename.txt" "c:\destdir\some001-directory\a filename.txt"
COPY /b "c:\sourcedir\project template\a#filename.txt" "c:\destdir\some001-directory\a001-filename.txt"