26

I have a bunch folders within folders. Like this

Root Folder
    -- Folder 1
    -- Folder 2
    -- Folder 3
    -- Folder 4

I want to collapse all folders so that all files under folder1, folder 2, folder 3, ... folder n exist under root folder.

What is the quickest way to do this in windows?

1
  • 6
    It depends, how would you want to handle duplicate file names?
    – Mark Allen
    Feb 22, 2013 at 22:45

4 Answers 4

31

You can flatten in Windows Explorer by navigating to the folder you wish to flatten and searching for System.Kind:<>folder to exclude folders from the results.

You can then select all the files with CTRL+A and copy and paste them into a new folder. Note that Windows Explorer will ask you how to deal with duplicate filenames.

enter image description here

5
  • 2
    note that for this to work you need to type "folder" in the corresponding localized translation (for example, in italian is System.Kind:<>cartella)
    – JohnKiller
    Oct 8, 2018 at 10:49
  • 2
    This is a very elegant solution. Thank you. Jul 10, 2020 at 13:05
  • 1
    Such a great a solution, allowed to copy all the photos under the DCIM folder on my card from the resulting search folder and then upload all easily to Google Photos
    – boardtc
    Jan 3, 2021 at 20:17
  • 1
    This is a hell of a tip. Great stuff.
    – dartacus
    Jan 14, 2021 at 14:36
  • 1
    absolutely brilliant solution
    – warsong
    Jun 17, 2023 at 19:23
24

There's no reason to use special tools or even scripting. Just use the search function in Explorer.

  1. Open the folder you wish to flatten in Explorer.
  2. Create a new folder, select all files (but not folders), and drag them to that folder (This will avoid getting two copies of those files.)
  3. In the search box (the one on the right of the address bar), type in * and press Enter.
  4. After the list populates, right click and select all, then right click and Cut.
  5. Press the back button to get back to the original folder, then right-click and paste.
  6. If you have any duplicate names, you will be prompted on how to deal with this. Choose the most appropriate option for your use case. (I would assume it would be to copy both files.) To avoid being prompted again, be sure to apply this to all files with the checkbox at the bottom.
  7. Select all folders, make sure they are empty by looking at the popup about the number of files selected, and then delete them.

If you would rather have a script so you can just start it and forget it, that can also be done. The command to replace mv *\* . is pretty easy (for /r %f in (*.*) do @move "%~f" .) but I'm sure you'd like to handle duplicates, without leaving them behind as in @Nicole Hamilton's answer. Appending a number to the filename of duplicates is probably the easiest way to do it.

Copy and paste the following batch file into Notepad and save it as "flatten.cmd" (including the quotation marks):

@echo off
cd "%~1"
md tempryfolder
move *.* tempryfolder
for /r %%f in ("*.*") do call :START "%%~f"
for /r /d %%f in (*.*) do rd "%%~f" 
GOTO :EOF
:START
setlocal
If exist "%~n1%~x1" set /a num=2
:LOOP
If exist "%~n1%num%%~x1" (
    set /a num+=1
    goto loop
)
move "%~1" "%~n1%num%%~x1"

To use the script, simply drag the folder you wish to flatten on top of it.

11
  • 1
    Similar but easier to understand: superuser.com/a/523854/433830 Feb 9, 2018 at 13:32
  • Note: this script is essentially a fork bomb. I'm using it on a folder with thousands of subdirectories and tens of thousands of subfiles and the memory footprint is slowly increasing. I don't think I'm going to run into OOM issues, but it's something to keep in mind.
    – Nzall
    Nov 23, 2018 at 7:53
  • @Nzall I have no problem believing that it could do that, but I would blame Microsoft, not my code. All I do is call a subroutine in the batch file multiple times. And I never run more than one at time: each subroutine runs until completion, running only one process at a time. How much memory are we talking about being used?
    – trlkly
    Nov 24, 2018 at 0:37
  • @trlkly At one point it went up to 2 GB, although I did have a quite large amount of folders and subfolders, around 75,000 files and thousands of folders. A few moments after it dropped back down to around 8-900 MB. There were loads of duplicate files though. I was flattening 12 copies of a 7,500 file Javascript library so I could test how certain software would handle a folder with tens of thousands of files.
    – Nzall
    Nov 25, 2018 at 21:35
  • @Nzall That's incredibly weird to me. Nothing the script does should do that. It's one subroutine that reuses a single variable to increment the file. I may have to ask what could cause such large memory usage on SO or something.
    – trlkly
    Nov 26, 2018 at 5:06
0

This kind of thing is easy with a Unix shell. Here's what you could do with my own Hamilton C shell (including the free version.) You could do something very similar with Cygwin bash.

mv *\* .

If your directory is really huge, it's possible that could wildcard into too long a command line for Windows to pass to a child process. (The Windows CreateProcess call limits the argument list to 32K Unicode characters.) But the C shell has no limit internally, so you could iterate over the whole list this way:

foreach i ( *\* )
   mv $i .
end

To @MarkAllen's point above, this kind of assumes there are no duplicate names. If there are, the later copies in the list will overwrite the older ones. If that's a concern, you could iterate over the files, mv'ing them only if you're not overwriting. The :t operator is the tail operator. The -e operator is the file exists test.

foreach i ( *\* )
   if ( -e $i:t ) then
      echo -2 $i not moved because it already exists
   else
      mv $i .
   end
end

This still leaves the empty directories, which maybe you don't want after they've been emptied. That could be the next iteration if it mattered.

4
  • Using cygwin >mv * . mv: cannot stat `*': No such file or directory Feb 23, 2013 at 0:00
  • In Cygwin bash, mv */* . works for me. Feb 23, 2013 at 0:18
  • 4
    Some people are so fixed in UNIXism... If you really want to do scripting in Windows 7, there's PowerShell, you don't need some bogus bash simulator like Cygwin.
    – user127350
    Feb 23, 2013 at 23:53
  • You don't even need PowerShell. The regular command line still exists and can do the same things. See my answer below.
    – trlkly
    Apr 16, 2014 at 3:56
-1

i m using this one - in order to reduce my folders https://raw.githubusercontent.com/nick7ikin/bash_flatten_folder/master/flatten_folder.sh

2
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.
    – Joseph
    Feb 25, 2021 at 16:22
  • it s about giving the reputation to the author. Ironic, denying/down voting a solution that isn't using the "feature" overwriting files with the same name or having interruption behaviors.
    – inselberg
    Mar 5, 2021 at 18:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .