Flatten Folder Hierarchy Button

Hello,
I tried searching for a button that could manage the following task, but couldn't find one.
I'd like to flatten the folder structure inside all selected folders (copy all files to corresponding child).

Example: We select folderA, folderB, and folderC:

folderA\fileA
folderA\fileB
folderA\fileC

folderB\subfolder1A\fileA
folderB\subfolder1A\fileB
folderB\subfolder1B\fileC
folderB\subfolder1B\fileD

folderC\subfolder1\fileA
folderC\subfolder1\subfolder2\fileB
folderC\subfolder1\subfolder2\fileC
folderC\subfolder1\subfolder2\subfolder3\fileD
folderC\fileE

Expected Output:

folderA\fileA (no changes here)
folderA\fileB
folderA\fileC

folderB\fileA
folderB\fileB
folderB\fileC
folderB\fileD

folderC\fileA
folderC\fileB
folderC\fileC
folderC\fileD
folderC\fileE

Max. needed interleaving: 3 subfolders.

I hope this is possible somehow. :slight_smile:
Thanks for everyone's help.

This thread might be useful, but it's about flattening everything into the current directory, rather than flattening each sub-directory separately.

Do you care what the filenames are after the flattening? If not then there's a pretty easy way to do it. Otherwise, it's probably still possible but might take some thought.

Thank you for the quick reply.
I have already read the thread you mentioned, but that's not what I want to achieve here. I already use this button for other tasks though. :slight_smile:

I'd like the filenames to be preserved, if that's possible.

Thanks again!!

Edit: All files have unique filenames (my example was a bit unclear).
(Couldn't edit my previous post)

To do something like this I'd either put Opus in a dual pane lister mode, then I'd put one of the panes in flat mode and move the files in flat view over to the other lister pane. Opus will prompt you on how to move the files but that should do it.

But if you have to do this a lot to a lot of folders and files, it may be better to use a script. I'm an old time batch file script writer so I'm prone to using batch files even though they have some limitations, such as failing when they encounter certain file or folder name characters like &.

Below is a screen shot of a button I have set up that should do what you want. The button sends the currently selected folder names to a batch file named "Move Subfolder Files to Parent Folder.cmd". The batch file, which I've also posted below, then does everything else.


@echo off
setlocal enabledelayedexpansion
set SRC=%1
if "%2" neq "Opus" goto :oops1
if "%~1" equ "" goto :oops2

for /r %SRC% %%a in (*) do (
	call :process "%%a" %SRC%
)
exit

:process
if "%~dp1" equ "%~2" goto :EOF

set X=%~1
rem IF THERE IS NO NAME CLASH, MOVE THE FILE
if not exist "%~2%~nx1" (
	move "%X%" "%~2"
	) else (
	rem HOWEVER IF THERE IS A NAME CLASH...
	for /l %%b in (1,1,1000) do (
		if not exist "%~2%~n1_%%b%~x1" (
			move "%X%" "%~2%~n1_%%b%~x1"
			goto :EOF
		)
	)
)
goto :EOF


:oops1
echo This script must be run from Opus
pause
exit

:oops2
echo You must have folders selected
pause
exit

Wow, first of all thank you so much for your work. :slight_smile:
I created the button and the .cmd file from your code and it works just flawless!! For such a long time I was looking for exactly this behaviour.
This button will save me so many clicks (I previously did as you mentioned, with a dual pane and Flat View) ...

If you have the time, could you please change the script so that it deletes the empty folders as well, then it would be perfect!

Thanks again JohnZeman for this button!! :slight_smile:

Give this version of the script a try. After moving the files the script will look for up to 10 levels of empty subdirectories to remove.
If you need more than that look in the script for the instructions on what to change to remove more.

@echo off
setlocal enabledelayedexpansion
set SRC=%1
if "%2" neq "Opus" goto :oops1
if "%~1" equ "" goto :oops2

:: option to delete empty subdirectories,
:: to preserve them comment out the next line
set DELSUBDIRS=true

for /r %SRC% %%a in (*) do (
	call :process "%%a" %SRC%
)

:: NEXT REMOVE EMPTY SUBDIRECTORIES
if not defined DELSUBDIRS exit

pushd %SRC%
:: The next loop makes 10 passes to remove 10 levels of empty directories
:: If you need more than 10 passes, increase the 10 in (1,1,10)
:: to a higher number
for /L %%a IN (1,1,10) do (
	for /f "delims=*" %%a in ('dir /a:d/b/s "*"') do (
		dir /a:-d "%%a\">NUL 2>NUL
		if errorlevel 1 (
			rd "%%a\" 2>NUL
		)
	)
)
popd
exit

:: //////////////////////////////////////////////


:process
if "%~dp1" equ "%~2" goto :EOF

set X=%~1
rem IF THERE IS NO NAME CLASH, MOVE THE FILE
if not exist "%~2%~nx1" (
	move "%X%" "%~2"
	) else (
	rem HOWEVER IF THERE IS A NAME CLASH...
	for /l %%b in (1,1,1000) do (
		if not exist "%~2%~n1_%%b%~x1" (
			move "%X%" "%~2%~n1_%%b%~x1"
			goto :EOF
		)
	)
)
goto :EOF


:oops1
echo This script must be run from Opus
pause
exit

:oops2
echo You must have folders selected
pause
exit

Hello,
thanks once again, the script works perfect! :thumbsup:
I reduced the iterations to 3, which is enough in my case.

Unfortunately, I have one problem with it, let me try to explain it:
When I start the script, it opens one cmd window per folder. If I work on more than ~10 folders, the load on the system seems so high due to all those cmd windows and threads, that Windows changes to the basic color scheme (without Aero). This wouldn't be a problem as I would simply restart the Desktop Window Manager (dwm.exe) Service when the script has finished (or it would auto-restart). But what also happens is that for every file inspected (?), a new thread is opened in dopus.exe.
The thread is called "4052, 7.941.773, dopuslib.dll!DoesExeFileContainZip+0x6012c" and it puts heavy load on dopus.exe, which then becomes unstable so that I need to restart DOpus completely from within Process Explorer.
It seems the problem has something to do with the ZIP/RAR plugin (there were some .rar files in those directories I worked at).

I hope this can be solved somehow.
Greetings :slight_smile:

put @sync: at the start of the line in the Opus button, so it runs things one at a time.

Now it's absolutely perfect (and doesn't conflict with DWM or Opus any more). :slight_smile:
Thank you both for all your help and time!!