In Windows, I need to recursively delete a directory except for a short list of files to be kept. The files may be nested in subdirectories.

I tried making the files read-only before running "rmdir /s", but it doesn't work. Read-only files cannot be deleted directly, but they are deleted when inside a subdirectory being deleted with "rmdir /s".

Any other ideas?


As far as I know you really can't have it both ways -- either the delete is recursive (everything goes) or it is not recursive (you explicitly list what you want gone).

The only reason the kind of read-only trick you tried works on Unix systems is because the failure/error propagates up the tree (you can't delete something that still has children), and it would appear from your test that Windows is less particular about that.

| improve this answer | |
  • Windows won't let you remove a non-empty directory, but the /s option for rmdir overrides the read-only flag. It would work if you changed the permissions on the files to read-only rather than setting the flag. – Harry Johnston Nov 12 '12 at 3:11
  1. Search for desired files.
  2. When found, copy desired files/folder tree to temporary location.
    • Robocopy with the correct options can preserve attributes and time stamps.
  3. Delete directory.
  4. Copy files/folder tree back to original location.
  5. ...?
  6. Profit!

A better scripter than I could probably automate the whole thing in a couple lines, using robocopy, even. Off the top of my head, I'm thinking maybe you copy out the list of files you want and use the /MIR option to blow away everything in the original directory that's not in the target directory.

| improve this answer | |

I was able to do this with some batch code, but it's fairly long:

setlocal enabledelayedexpansion

:: Delete files not containing "foo"
for /r MyDir %%i in (*) do (
  set temp=%%~nxi
  if "!temp:foo=!"=="!temp!" (
    del "%%i"

:: Build recursive list of dirs, sorted by deepest first
set dirs=
for /r MyDir /d %%i in (*) do (
  set dirs="%%i" !dirs!

:: Delete dirs.  Nonempty dirs will be skipped.
for %%i in (%dirs%) do (
  rmdir %%i
| improve this answer | |

Hidden files are not deleted.

  1. attrib +h for the files not to delete
  2. delete all the files
  3. del the empty directories
  4. attrib +h the files saved.

Vg :

for /f "delims=" %i in ('dir "My Dir\\*.log" /b /s') do attrib +h "%i"
for /f "delims=" %i in ('dir "My Dir" /b /s') do del "%i" /q
rmdir /s
for /f "delims=" %i in ('dir "My Dir" /b /s /ah') do attrib -h "%i"
| improve this answer | |
  • Hidden files are not deleted. Under what circumstances? They most certainly are when I go to delete a directory, as well as they way the OP tried doing it at first. – HopelessN00b Nov 12 '12 at 16:32
  • Within a cmd window, you can't delete hidden files, just because the dir command can't see them as they are hidden – Jean-Paul Feltin Nov 12 '12 at 16:37
  • Not really the case, no. Try dir /a or attrib. – HopelessN00b Nov 12 '12 at 16:41
  • And that's why you have – Jean-Paul Feltin Nov 12 '12 at 16:44
  • Sorry. That'why you have 'dir "My Dir" /b /s' and not 'dir "My Dir" /b /s /a' in the for command – Jean-Paul Feltin Nov 12 '12 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.