Search code examples
batch-filexcopysubdirectory

Moving and renaming files, keeping extension but include sub directories in batch file


Forgive me if this is nor the place to ask these questions, I am new to batch and scripts and a bit new to these kind of posts...

I have a folder that will receive files and folders, I want to run a script that looks at the directory and renames all files in each subfolder numerically, and moves them if possible.

For example I have something that looks like the following

Recieved_File_Folder
     |_folder1
     | |_file1.txt
     | |_file2.bmp
     |_folder2
     | |_file4.exe
     | |_file5.bmp
     |__file9.txt
     |__file10.jpg

I would like to be able to look in every directory and move it to something like this, keeping in mind the names of the files will be random and I want to keep the extension intact also.

Renamed_Folder
    |_folder1
    | |_1.txt
    | |_2.bmp
    |_folder2
    | |_1.exe
    | |_2.bmp
    |__1.txt
    |__2.jpg

I have spent alot of time on this and am not doing too well with it, any help would be very greatly appreciated!! Thank you in advance!


Solution

  • This little script should do the trick:

    @ECHO OFF
    
    SETLOCAL ENABLEDELAYEDEXPANSION
    
    FOR /F "tokens=1 delims=" %%A IN ('DIR /B /S /A:D') DO (
    
       SET /A FILE_COUNTER=1
    
       FOR /F "tokens=1 delims=" %%B IN ('DIR /B /A:-D "%%A"') DO (
          CALL :RENAME "%%A%%B" !FILE_COUNTER!
          SET /A FILE_COUNTER=FILE_COUNTER+1
       )   
    )   
    
    ENDLOCAL    
    GOTO :EOF    
    
    :RENAME
    
    SET OLD_PATH="%~f1"
    SET NEW_FILE_NAME="%2%~x1"
    REN %OLD_NAME% %NEW_NAME%    
    GOTO :EOF
    

    Use it with care as the script will not ask for confirmation, so watch out where you start it from!

    How does it work:

    • the first FOR-loop lists all sub directories recursively, starting with the current directory (using DIR /B /S /A:D) and passes the full path to the loop body via the variable %%A
    • in the first loops body a variable FILE_COUNTER is set to the value of 1
    • the second (inner) FOR-loop lists all files in the directory passed in by the outer loop (using DIR /B /A:-D "%%A") and passes the file's full path to its body via the variable %%B
    • in the inner loop body the sub routine :RENAME is called with the full file name the current FILE_COUNTER value as its parameters
    • the :RENAME sub routine uses its parameters to form the new file name and issues a rename command REN
    • after the sub routine returns, the current FILE_COUNTER value is increased by one (SET /A FILE_COUNTER=FILE_COUNTER+1)