windows - How to rename multiple folders while keeping their files subdirectories

06
2014-04
  • nixda

    I want to rename multiple folders and keep all files and subdirectories in tact.
    Windows batch commands like xcopy and move can't handle every case*.

    I set up two columns with old paths and new paths.

    OLD PATH            NEW PATH
    C:\dir1\dir3\dir7   C:\a1\a2\a3      
    C:\dir1\dir4\dir8   C:\b1\b2\b3      
    C:\dir2\dir5\dir9   C:\c1\c2\c3      
    ...
    C:\dir2\dir6\dir0   C:\d1\d2\d3      
    

    Difficulties: More than one folder per line needs to be renamed; last listed folders like dir7 can have multiple subdirectories; file time stamps shouldn't be modified


    * xcopy can't move, it only copies. That's a problem if you haven't enough space to copy and delete big data.
    The move command doesn't move subdirectories, only files

  • Answers
  • Rik

    The most simple (straightforward) batchfile version would be like this:

    call :robo "C:\dir1\dir3\dir7"   "C:\a1\a2\a3"
    call :robo "C:\dir1\dir4\dir8"   "C:\b1\b2\b3"
    call :robo "C:\dir2\dir5\dir9"   "C:\c1\c2\c3"
    echo etc...
    call :robo "C:\dir2\dir6\dir0"   "C:\d1\d2\d3"
    goto:eof
    
    :robo
    robocopy %1 %2 /MOVE /E
    goto:eof
    

    You would need to quote the directories in case they have spaces.

    For reading the directories out of a file you would do this:

    directories.txt:

    C:\dir1\dir3\dir7,C:\a1\a2\a3
    C:\dir1\dir4\dir8,C:\b1\b2\b3
    C:\dir2\dir5\dir9,C:\c1\c2\c3
    C:\dir2\dir6\dir0,C:\d1\d2\d3
    

    No need for quotes and separate them with a comma. Then in the batchfile:

    FOR /F "tokens=1-2* delims=," %%A IN (directories.txt) DO (
      robocopy "%%A" "%%B" /MOVE /E
    )
    

    Also here... if you would like to see what robocopy does first use the /L.

    If you have a file like this (with spaces to align the first and second column) you would need to add some code to strip the leading and trailing spaces from the directories:

    Again the directories.txt:

    C:\dir1\dir3\dir7\sada\asda ,  C:\a1\a2\a3
    C:\dir1\dir4\dir8           ,  C:\b1\b2\b3
    C:\dir2\dir5\dir9           ,  C:\c1\c2\c3
    ...
    C:\dir2\dir6\dir0           , C:\d1\d2\d3
    

    And this as batchfile:

    @echo off
    setlocal enabledelayedexpansion
    FOR /F "tokens=1-2* delims=," %%A IN (directories.txt) DO (
      call :trim dir1 %%A
      call :trim dir2 %%B
      robocopy "!dir1!" "!dir2!" /MOVE /E
    )
    goto:eof
    
    :trim
    set trimmed=%2
    for /f "tokens=* delims= " %%c in ("%trimmed%") do set trimmed=%%c
    for /l %%c in (1,1,100) do if "!trimmed:~-1!"==" " set trimmed=!trimmed:~0,-1!
    set "%~1=%trimmed%"
    goto:eof
    

    Note: No error checking is done to see if the directories really exists or if only one column is filled... etc...
    (but of course that could be added).

  • nixda

    The solution I came up with, was very simple. You just need Excel and Robocopy. The latter one is pre-installed since Vista. Windows XP users can get it via Windows Server 2003 Resource Kit

    Prepare an Excel file where your old paths are saved in column A and new ones right to it in column B. Open the VBA editor and paste this macro.

    Sub MoveFolders()
      For i = 1 To ActiveSheet.UsedRange.Rows.Count
        Shell ("CMD /C robocopy " & Cells(i, 1) & " " & Cells(i, 2) & " /MOVE /E")
      Next i
    End Sub
    

    It steps through all used cells of column A and calls Robocopy via command line and the following syntax: CMD> robocopy source destination /MOVE /E

    If you're unsure use this line for testing purposes instead. It will list all files without actually moving them:

    Shell ("CMD /K robocopy " & Cells(i, 1) & " " & Cells(i, 2) & " /MOVE /E /L")
    

    There are many more usefull robocopy switches to play around with.


  • Related Question

    Windows batch file: rename files (possibly in multiple folders) based on input file (of target filenames)
  • cMP

    I am a Batch-newbie...

    This "tool" is to automate the slimming down of Windows (XP) by disabling certain system driver, DLL and EXE files. Instead of outright deletion, I wish to rename-in-place, thus "removing" them from the OS, but not losing sight of where they belong (should any need to be "restored"). Renaming is accomplished by appending a new suffix to the existing filename (eg: "wdmaud.drv.group_1") The renaming suffix should be another input variable.

    The target-list is approx. 1100 files long (divided into various groups/phases), so manual renaming is out of the question. Each group will be processed in a separate run of the batch file, varying the target-list input file for each execution.

    Target-list is plain text file, one filename per line (no other data in the files). Number of entries per group varies. Target list will look like this:

        -- example start --
        netapi.dll
        netcfgx.dll 
        netdde.exe 
        netevent.dll 
        nic1394.sys
        -- example end --
    

    Filenames may be in UPPER, lower, or MiXeD case. The files may be present in more than one folder in the C:\Windows hierarchy - or may not be present at all. If a file is not found anywhere in the system, it's name should be written to a text file, one-entry-per-line.

    The specific folders of interest are:

        C:\WINDOWS\
        C:\WINDOWS\system\
        C:\WINDOWS\system32\
        C:\WINDOWS\system32\dllcache
        C:\WINDOWS\system32\drivers
    

    ...but may change as development proceeds.

    Based on a reply at stackoverflow.com, I've got started thus:

        @echo off
    
        set suffix=GROUP_1
        set targetlist=GROUP_1.txt
        set dirlist=folders.txt
    
        for /f "tokens=*" %%f in (%targetlist%) do (
          for /f "tokens=*" %%d in (%dirlist%) do (
            if exist "%%d\%%f" ren "%%d\%%f.%%suffix"
               echo %%f found in %%d >> foundlist.txt
          )
        )
    

    ==============================================================================

        :: -----------------------------------------------------------------::
        :: Batch Process to Rename-In-Place System Files from an Input List ::
        :: -----------------------------------------------------------------::
    
        @echo off
        :: >> clear files from previous run <<
        if exist RENAMED_files.txt  DEL RENAMED_files.txt
        if exist NOTFound_files.txt DEL NOTFound_files.txt
    
        ::  >> file rename-suffix reflects step name <<
        set suffix=Steppe_01
    
        ::  >> target file list to rename <<
        set targetlist=Steppe_01_files.txt
    
        ::  >> list of folders to search  <<
        set dirlist=folders.txt
    
        ::  >> PROCESS <<
    
        for /f "tokens=*" %%f in (%targetlist%) do (
          echo. >> NOTFound_files.txt
          for /f "tokens=*" %%d in (%dirlist%) do (
            if NOT exist "%%d\%%f"          echo %%f  not in %%d >> NOTFound_files.txt
            if exist     "%%d\%%f"          REN "%%d\%%f" "%%f.%suffix%"
            if exist     "%%d\%%f.%suffix%" echo renamed  %%f  in %%d >> RENAMED_files.txt
          )
        )
    
        ::  >> end of process <<
    

  • Related Answers
    Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.