Search code examples
windowsbatch-filebatch-rename

Organize files with batch script


I need to somehow copy all files from source folder(including subfolders) to destination folder keeping the subfolders name as a file name.

Using batch file on windows.

Example:

sourceFolder\packed1.bin
sourceFolder\data1\packed1.bin
sourceFolder\data1\packed2.bin
sourceFolder\data1\zz\packed1.bin
sourceFolder\data1\aa\packed1.bin
sourceFolder\data1\aa\22\packed1.bin

should become...

destinationFolder\packed1.bin
destinationFolder\data1-packed1.bin
destinationFolder\data1-packed2.bin
destinationFolder\data1-zz-packed1.bin
destinationFolder\data1-aa-packed1.bin
destinationFolder\data1-aa-22-packed1.bin

I tried using goto but I cannot keep the track of which directory I am in and then return to it.

@echo off
setlocal EnableDelayedExpansion

set mypath=%cd%
set "_orig=%mypath%\datafolder"
set "_origCurr=%_orig%"
set "_dest=%mypath%\untree\"

set procDirs
set /a procDirsL=0
set currDirS=""
set /a isProc=0

:gofolders
for /d %%D in ("%_dest%\*.*") do (
set currDirS=%currDirS%\%%D
set procDirs[!procDirsL!]

set /a procDirsL=!procDirsL!+1


goto gofolders
)

:dofiles
for /f %%F in ("%_dest%\*.*") do (

)
goto gofolders

Solution

  • @echo off
    setlocal
    
    rem Set target and destination paths.
    set "target=%cd%\sourceFolder"
    set "dest=%cd%\destinationFolder"
    
    rem Make dest dir if needed.
    if not exist "%dest%" md "%dest%"
    
    rem Recurse target and get filepath of .bin files.
    for /r "%target%" %%A in (*.bin) do call :moveToDest %%A
    exit /b
    
    :moveToDest
    setlocal
    set "oldname=%~1"
    
    rem Remove target from the filepath.
    call set "newname=%%oldname:%target%=%%"
    if not defined newname (
        >&2 echo target is undefined
        exit /b 1
    )
    
    rem Remove leading \.
    if "%newname:~,1%" == "\" set "newname=%newname:~1%"
    
    rem Replace \ with -.
    set "newname=%newname:\=-%"
    
    rem Copy new named file to dest.
    copy "%oldname%" "%dest%\%newname%" >nul
    if errorlevel 1 (
        >&2 echo Failed to copy "%oldname%" to "%dest%\%newname%"
        exit /b 1
    )
    exit /b
    

    Set target and dest before executing.

    As the destination files are renamed and copied to destination with no subfolder structure, making the destination folder is done at the start only once.

    The target folder is recursed with the for loop and gets all the fullpaths to the .bin files. The label :moveToDest is called with argument of the fullpath to each .bin file.

    In the label :moveToDest, the argument passed is set to oldname. The target path is removed and leading backslash if needed. This sets oldname as a relative path from the target path. The backslashs are replaced with dashes to create the filename for copy. Copies the .bin file using copy to copy from the target to the destination with the new filename.