How to remove all empty directories in a subtree?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








141















How can I remove all empty directories in a subtree? I used something like



find . -type d -exec rmdir 2>/dev/null ;


but I needs to be run multiple times in order to remove directories containing empty directories only. Moreover, it's quite slow, especially under cygwin.










share|improve this question
























  • See also emacs.stackexchange.com/q/12190/2264 for an emacs solution.

    – Sean Allred
    May 6 '15 at 15:13

















141















How can I remove all empty directories in a subtree? I used something like



find . -type d -exec rmdir 2>/dev/null ;


but I needs to be run multiple times in order to remove directories containing empty directories only. Moreover, it's quite slow, especially under cygwin.










share|improve this question
























  • See also emacs.stackexchange.com/q/12190/2264 for an emacs solution.

    – Sean Allred
    May 6 '15 at 15:13













141












141








141


36






How can I remove all empty directories in a subtree? I used something like



find . -type d -exec rmdir 2>/dev/null ;


but I needs to be run multiple times in order to remove directories containing empty directories only. Moreover, it's quite slow, especially under cygwin.










share|improve this question
















How can I remove all empty directories in a subtree? I used something like



find . -type d -exec rmdir 2>/dev/null ;


but I needs to be run multiple times in order to remove directories containing empty directories only. Moreover, it's quite slow, especially under cygwin.







directory find rm






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 1 '11 at 22:08









Gilles

546k13011121625




546k13011121625










asked Mar 1 '11 at 21:48









maaartinusmaaartinus

1,88152124




1,88152124












  • See also emacs.stackexchange.com/q/12190/2264 for an emacs solution.

    – Sean Allred
    May 6 '15 at 15:13

















  • See also emacs.stackexchange.com/q/12190/2264 for an emacs solution.

    – Sean Allred
    May 6 '15 at 15:13
















See also emacs.stackexchange.com/q/12190/2264 for an emacs solution.

– Sean Allred
May 6 '15 at 15:13





See also emacs.stackexchange.com/q/12190/2264 for an emacs solution.

– Sean Allred
May 6 '15 at 15:13










6 Answers
6






active

oldest

votes


















197














Combining GNU find options and predicates, this command should do the job:



find . -type d -empty -delete



  • -type d restricts to directories


  • -empty restricts to empty ones


  • -delete removes each directory

The tree is walked from the leaves without the need to specify -depth as it is implied by -delete.






share|improve this answer




















  • 1





    -delete already implies -depth so you don't need to specify that manually.

    – jamadagni
    Sep 19 '14 at 2:31











  • Thanks, I didn't realize that. Answer updated.

    – Christophe Drevet-Droguet
    Sep 19 '14 at 15:57






  • 8





    I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty.

    – Greg Dubicki
    Aug 20 '16 at 12:49






  • 1





    Great, but doesn't work on my old SunOS hosts...

    – dokaspar
    Aug 8 '17 at 10:05






  • 1





    ! has a special meaning for the shell. You need to escape it. Something like: ! -name 'Completed' just before -delete should work. Or you just put a marker file in this directory.

    – Christophe Drevet-Droguet
    Apr 2 '18 at 8:34


















51














List the directories deeply-nested-first.



find . -depth -type d -exec rmdir ; 2>/dev/null


(Note that the redirection applies to the find command as a whole, not just to rmdir. Redirecting only for rmdir would cause a significant slowdown as you'd need to invoke an intermediate shell.)



You can avoid running rmdir on non-empty directories by passing the -empty predicate to find. GNU find tests the directory when it's about to run the command, so directories that have just been emptied will be picked up.



find . -depth -type d -empty -exec rmdir ;


Another way to speed up would be to group the rmdir invocations. Both are likely to be noticeably faster than the original, especially under Cygwin. I don't expect much difference between these two.



find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null
find . -depth -type d -exec rmdir + 2>/dev/null


Which method is faster depends on how many non-empty directories you have. You can't combine -empty with methods for grouping invocations, because then the directories that only contain empty directories aren't empty by the time find looks at them.



Another method would be to run multiple passes. Whether this is faster depends on a lot of things, including whether the whole directory hierarchy can remain in the disk cache between find runs.



while [ -n "$(find . -depth -type d -empty -print -exec rmdir +)" ]; do :; done


Alternatively, use zsh. The glob qualifier F matches non-empty directories, so /^F matches empty directories. Directories that only contain empty directories can't be matched so easily.



while rmdir **/*(/N^F); do :; done


(This terminates when rmdir receives an empty command line.)






share|improve this answer

























  • That's it. Instead of 90 seconds it takes 0.90 s.

    – maaartinus
    Mar 1 '11 at 22:14












  • @maaartinus: I'm curious: do you have a similar data set where you could try without -p? I wouldn't have thought it would make a difference.

    – Gilles
    Mar 1 '11 at 22:15






  • 3





    @maartinus — other little optimizations: adding -empty should work with this one (although I'm not sure exactly how much it'll gain). And very, very trivially, since you probably don't want to remove ., use -mindepth 1.

    – mattdm
    Mar 1 '11 at 22:19











  • It was not the removal but the process start up overhead, what took nearly all the time. I had overlooked the -depth argument, which makes rmdir -p useless. I've changed my comment already. The 90 s was my original attempt; there's nothing surprising here.

    – maaartinus
    Mar 1 '11 at 22:20






  • 2





    I realized we can remove the rmdir command call altogether, at least with GNU find, with this command: find . -depth -type d -empty -delete

    – Christophe Drevet-Droguet
    Jan 2 '14 at 14:26



















6














If you just tack a -p on your rmdir, that'll work in one pass. It won't be pretty or optimal, but it should get everything. That tells rmdir to remove any non-empty parent directories of the one you're removing.



You can save a little bit by adding the -empty test to find, so it doesn't bother with non-empty directories.






share|improve this answer
































    3














    find . -depth -type d -exec rmdir +



    is the simplest and standard compliant answer to this question.



    The other answers given here unfortunately all depend on vendor specific enhancements that do not exist on all systems.






    share|improve this answer


















    • 2





      This answer raises an error for each directory that cannot be deleted which may be less than desirable.

      – Willem van Ketwich
      Apr 13 '17 at 0:04


















    0














    find . -type d -printf "%d %pn" |
    sort -nr |
    perl -pe 's/^d+s//;' |
    while read dir; do
    (rmdir "$dir" > /dev/null 2>&1);
    done



    Here's how it works:



    1. Recursively list all the directories along with their depth

    2. Sort by descending order of their depth

    3. Filter out only the directory paths

    4. Run rmdir on the list one by one





    share|improve this answer






























      -1














      rm -r */ command worked easily for me. rm should require -f to forcefully remove directories with files. rm -r should only remove empty directories. I'm open to why this could be wrong. This should also leave files since */ only looks at folders.






      share|improve this answer


















      • 1





        I'd strongly recommend to test it thoroughly first as rm is primarily meant to remove files. While */ only matches directories, I have no idea what it does on deeper levels. I can also imagine that it works on some systems only.

        – maaartinus
        Jun 22 '18 at 19:30











      Your Answer








      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "106"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f8430%2fhow-to-remove-all-empty-directories-in-a-subtree%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      197














      Combining GNU find options and predicates, this command should do the job:



      find . -type d -empty -delete



      • -type d restricts to directories


      • -empty restricts to empty ones


      • -delete removes each directory

      The tree is walked from the leaves without the need to specify -depth as it is implied by -delete.






      share|improve this answer




















      • 1





        -delete already implies -depth so you don't need to specify that manually.

        – jamadagni
        Sep 19 '14 at 2:31











      • Thanks, I didn't realize that. Answer updated.

        – Christophe Drevet-Droguet
        Sep 19 '14 at 15:57






      • 8





        I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty.

        – Greg Dubicki
        Aug 20 '16 at 12:49






      • 1





        Great, but doesn't work on my old SunOS hosts...

        – dokaspar
        Aug 8 '17 at 10:05






      • 1





        ! has a special meaning for the shell. You need to escape it. Something like: ! -name 'Completed' just before -delete should work. Or you just put a marker file in this directory.

        – Christophe Drevet-Droguet
        Apr 2 '18 at 8:34















      197














      Combining GNU find options and predicates, this command should do the job:



      find . -type d -empty -delete



      • -type d restricts to directories


      • -empty restricts to empty ones


      • -delete removes each directory

      The tree is walked from the leaves without the need to specify -depth as it is implied by -delete.






      share|improve this answer




















      • 1





        -delete already implies -depth so you don't need to specify that manually.

        – jamadagni
        Sep 19 '14 at 2:31











      • Thanks, I didn't realize that. Answer updated.

        – Christophe Drevet-Droguet
        Sep 19 '14 at 15:57






      • 8





        I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty.

        – Greg Dubicki
        Aug 20 '16 at 12:49






      • 1





        Great, but doesn't work on my old SunOS hosts...

        – dokaspar
        Aug 8 '17 at 10:05






      • 1





        ! has a special meaning for the shell. You need to escape it. Something like: ! -name 'Completed' just before -delete should work. Or you just put a marker file in this directory.

        – Christophe Drevet-Droguet
        Apr 2 '18 at 8:34













      197












      197








      197







      Combining GNU find options and predicates, this command should do the job:



      find . -type d -empty -delete



      • -type d restricts to directories


      • -empty restricts to empty ones


      • -delete removes each directory

      The tree is walked from the leaves without the need to specify -depth as it is implied by -delete.






      share|improve this answer















      Combining GNU find options and predicates, this command should do the job:



      find . -type d -empty -delete



      • -type d restricts to directories


      • -empty restricts to empty ones


      • -delete removes each directory

      The tree is walked from the leaves without the need to specify -depth as it is implied by -delete.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Sep 19 '14 at 15:57

























      answered Jan 2 '14 at 14:34









      Christophe Drevet-DroguetChristophe Drevet-Droguet

      2,42211011




      2,42211011







      • 1





        -delete already implies -depth so you don't need to specify that manually.

        – jamadagni
        Sep 19 '14 at 2:31











      • Thanks, I didn't realize that. Answer updated.

        – Christophe Drevet-Droguet
        Sep 19 '14 at 15:57






      • 8





        I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty.

        – Greg Dubicki
        Aug 20 '16 at 12:49






      • 1





        Great, but doesn't work on my old SunOS hosts...

        – dokaspar
        Aug 8 '17 at 10:05






      • 1





        ! has a special meaning for the shell. You need to escape it. Something like: ! -name 'Completed' just before -delete should work. Or you just put a marker file in this directory.

        – Christophe Drevet-Droguet
        Apr 2 '18 at 8:34












      • 1





        -delete already implies -depth so you don't need to specify that manually.

        – jamadagni
        Sep 19 '14 at 2:31











      • Thanks, I didn't realize that. Answer updated.

        – Christophe Drevet-Droguet
        Sep 19 '14 at 15:57






      • 8





        I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty.

        – Greg Dubicki
        Aug 20 '16 at 12:49






      • 1





        Great, but doesn't work on my old SunOS hosts...

        – dokaspar
        Aug 8 '17 at 10:05






      • 1





        ! has a special meaning for the shell. You need to escape it. Something like: ! -name 'Completed' just before -delete should work. Or you just put a marker file in this directory.

        – Christophe Drevet-Droguet
        Apr 2 '18 at 8:34







      1




      1





      -delete already implies -depth so you don't need to specify that manually.

      – jamadagni
      Sep 19 '14 at 2:31





      -delete already implies -depth so you don't need to specify that manually.

      – jamadagni
      Sep 19 '14 at 2:31













      Thanks, I didn't realize that. Answer updated.

      – Christophe Drevet-Droguet
      Sep 19 '14 at 15:57





      Thanks, I didn't realize that. Answer updated.

      – Christophe Drevet-Droguet
      Sep 19 '14 at 15:57




      8




      8





      I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty.

      – Greg Dubicki
      Aug 20 '16 at 12:49





      I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty.

      – Greg Dubicki
      Aug 20 '16 at 12:49




      1




      1





      Great, but doesn't work on my old SunOS hosts...

      – dokaspar
      Aug 8 '17 at 10:05





      Great, but doesn't work on my old SunOS hosts...

      – dokaspar
      Aug 8 '17 at 10:05




      1




      1





      ! has a special meaning for the shell. You need to escape it. Something like: ! -name 'Completed' just before -delete should work. Or you just put a marker file in this directory.

      – Christophe Drevet-Droguet
      Apr 2 '18 at 8:34





      ! has a special meaning for the shell. You need to escape it. Something like: ! -name 'Completed' just before -delete should work. Or you just put a marker file in this directory.

      – Christophe Drevet-Droguet
      Apr 2 '18 at 8:34













      51














      List the directories deeply-nested-first.



      find . -depth -type d -exec rmdir ; 2>/dev/null


      (Note that the redirection applies to the find command as a whole, not just to rmdir. Redirecting only for rmdir would cause a significant slowdown as you'd need to invoke an intermediate shell.)



      You can avoid running rmdir on non-empty directories by passing the -empty predicate to find. GNU find tests the directory when it's about to run the command, so directories that have just been emptied will be picked up.



      find . -depth -type d -empty -exec rmdir ;


      Another way to speed up would be to group the rmdir invocations. Both are likely to be noticeably faster than the original, especially under Cygwin. I don't expect much difference between these two.



      find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null
      find . -depth -type d -exec rmdir + 2>/dev/null


      Which method is faster depends on how many non-empty directories you have. You can't combine -empty with methods for grouping invocations, because then the directories that only contain empty directories aren't empty by the time find looks at them.



      Another method would be to run multiple passes. Whether this is faster depends on a lot of things, including whether the whole directory hierarchy can remain in the disk cache between find runs.



      while [ -n "$(find . -depth -type d -empty -print -exec rmdir +)" ]; do :; done


      Alternatively, use zsh. The glob qualifier F matches non-empty directories, so /^F matches empty directories. Directories that only contain empty directories can't be matched so easily.



      while rmdir **/*(/N^F); do :; done


      (This terminates when rmdir receives an empty command line.)






      share|improve this answer

























      • That's it. Instead of 90 seconds it takes 0.90 s.

        – maaartinus
        Mar 1 '11 at 22:14












      • @maaartinus: I'm curious: do you have a similar data set where you could try without -p? I wouldn't have thought it would make a difference.

        – Gilles
        Mar 1 '11 at 22:15






      • 3





        @maartinus — other little optimizations: adding -empty should work with this one (although I'm not sure exactly how much it'll gain). And very, very trivially, since you probably don't want to remove ., use -mindepth 1.

        – mattdm
        Mar 1 '11 at 22:19











      • It was not the removal but the process start up overhead, what took nearly all the time. I had overlooked the -depth argument, which makes rmdir -p useless. I've changed my comment already. The 90 s was my original attempt; there's nothing surprising here.

        – maaartinus
        Mar 1 '11 at 22:20






      • 2





        I realized we can remove the rmdir command call altogether, at least with GNU find, with this command: find . -depth -type d -empty -delete

        – Christophe Drevet-Droguet
        Jan 2 '14 at 14:26
















      51














      List the directories deeply-nested-first.



      find . -depth -type d -exec rmdir ; 2>/dev/null


      (Note that the redirection applies to the find command as a whole, not just to rmdir. Redirecting only for rmdir would cause a significant slowdown as you'd need to invoke an intermediate shell.)



      You can avoid running rmdir on non-empty directories by passing the -empty predicate to find. GNU find tests the directory when it's about to run the command, so directories that have just been emptied will be picked up.



      find . -depth -type d -empty -exec rmdir ;


      Another way to speed up would be to group the rmdir invocations. Both are likely to be noticeably faster than the original, especially under Cygwin. I don't expect much difference between these two.



      find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null
      find . -depth -type d -exec rmdir + 2>/dev/null


      Which method is faster depends on how many non-empty directories you have. You can't combine -empty with methods for grouping invocations, because then the directories that only contain empty directories aren't empty by the time find looks at them.



      Another method would be to run multiple passes. Whether this is faster depends on a lot of things, including whether the whole directory hierarchy can remain in the disk cache between find runs.



      while [ -n "$(find . -depth -type d -empty -print -exec rmdir +)" ]; do :; done


      Alternatively, use zsh. The glob qualifier F matches non-empty directories, so /^F matches empty directories. Directories that only contain empty directories can't be matched so easily.



      while rmdir **/*(/N^F); do :; done


      (This terminates when rmdir receives an empty command line.)






      share|improve this answer

























      • That's it. Instead of 90 seconds it takes 0.90 s.

        – maaartinus
        Mar 1 '11 at 22:14












      • @maaartinus: I'm curious: do you have a similar data set where you could try without -p? I wouldn't have thought it would make a difference.

        – Gilles
        Mar 1 '11 at 22:15






      • 3





        @maartinus — other little optimizations: adding -empty should work with this one (although I'm not sure exactly how much it'll gain). And very, very trivially, since you probably don't want to remove ., use -mindepth 1.

        – mattdm
        Mar 1 '11 at 22:19











      • It was not the removal but the process start up overhead, what took nearly all the time. I had overlooked the -depth argument, which makes rmdir -p useless. I've changed my comment already. The 90 s was my original attempt; there's nothing surprising here.

        – maaartinus
        Mar 1 '11 at 22:20






      • 2





        I realized we can remove the rmdir command call altogether, at least with GNU find, with this command: find . -depth -type d -empty -delete

        – Christophe Drevet-Droguet
        Jan 2 '14 at 14:26














      51












      51








      51







      List the directories deeply-nested-first.



      find . -depth -type d -exec rmdir ; 2>/dev/null


      (Note that the redirection applies to the find command as a whole, not just to rmdir. Redirecting only for rmdir would cause a significant slowdown as you'd need to invoke an intermediate shell.)



      You can avoid running rmdir on non-empty directories by passing the -empty predicate to find. GNU find tests the directory when it's about to run the command, so directories that have just been emptied will be picked up.



      find . -depth -type d -empty -exec rmdir ;


      Another way to speed up would be to group the rmdir invocations. Both are likely to be noticeably faster than the original, especially under Cygwin. I don't expect much difference between these two.



      find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null
      find . -depth -type d -exec rmdir + 2>/dev/null


      Which method is faster depends on how many non-empty directories you have. You can't combine -empty with methods for grouping invocations, because then the directories that only contain empty directories aren't empty by the time find looks at them.



      Another method would be to run multiple passes. Whether this is faster depends on a lot of things, including whether the whole directory hierarchy can remain in the disk cache between find runs.



      while [ -n "$(find . -depth -type d -empty -print -exec rmdir +)" ]; do :; done


      Alternatively, use zsh. The glob qualifier F matches non-empty directories, so /^F matches empty directories. Directories that only contain empty directories can't be matched so easily.



      while rmdir **/*(/N^F); do :; done


      (This terminates when rmdir receives an empty command line.)






      share|improve this answer















      List the directories deeply-nested-first.



      find . -depth -type d -exec rmdir ; 2>/dev/null


      (Note that the redirection applies to the find command as a whole, not just to rmdir. Redirecting only for rmdir would cause a significant slowdown as you'd need to invoke an intermediate shell.)



      You can avoid running rmdir on non-empty directories by passing the -empty predicate to find. GNU find tests the directory when it's about to run the command, so directories that have just been emptied will be picked up.



      find . -depth -type d -empty -exec rmdir ;


      Another way to speed up would be to group the rmdir invocations. Both are likely to be noticeably faster than the original, especially under Cygwin. I don't expect much difference between these two.



      find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null
      find . -depth -type d -exec rmdir + 2>/dev/null


      Which method is faster depends on how many non-empty directories you have. You can't combine -empty with methods for grouping invocations, because then the directories that only contain empty directories aren't empty by the time find looks at them.



      Another method would be to run multiple passes. Whether this is faster depends on a lot of things, including whether the whole directory hierarchy can remain in the disk cache between find runs.



      while [ -n "$(find . -depth -type d -empty -print -exec rmdir +)" ]; do :; done


      Alternatively, use zsh. The glob qualifier F matches non-empty directories, so /^F matches empty directories. Directories that only contain empty directories can't be matched so easily.



      while rmdir **/*(/N^F); do :; done


      (This terminates when rmdir receives an empty command line.)







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Aug 25 '12 at 22:42

























      answered Mar 1 '11 at 22:08









      GillesGilles

      546k13011121625




      546k13011121625












      • That's it. Instead of 90 seconds it takes 0.90 s.

        – maaartinus
        Mar 1 '11 at 22:14












      • @maaartinus: I'm curious: do you have a similar data set where you could try without -p? I wouldn't have thought it would make a difference.

        – Gilles
        Mar 1 '11 at 22:15






      • 3





        @maartinus — other little optimizations: adding -empty should work with this one (although I'm not sure exactly how much it'll gain). And very, very trivially, since you probably don't want to remove ., use -mindepth 1.

        – mattdm
        Mar 1 '11 at 22:19











      • It was not the removal but the process start up overhead, what took nearly all the time. I had overlooked the -depth argument, which makes rmdir -p useless. I've changed my comment already. The 90 s was my original attempt; there's nothing surprising here.

        – maaartinus
        Mar 1 '11 at 22:20






      • 2





        I realized we can remove the rmdir command call altogether, at least with GNU find, with this command: find . -depth -type d -empty -delete

        – Christophe Drevet-Droguet
        Jan 2 '14 at 14:26


















      • That's it. Instead of 90 seconds it takes 0.90 s.

        – maaartinus
        Mar 1 '11 at 22:14












      • @maaartinus: I'm curious: do you have a similar data set where you could try without -p? I wouldn't have thought it would make a difference.

        – Gilles
        Mar 1 '11 at 22:15






      • 3





        @maartinus — other little optimizations: adding -empty should work with this one (although I'm not sure exactly how much it'll gain). And very, very trivially, since you probably don't want to remove ., use -mindepth 1.

        – mattdm
        Mar 1 '11 at 22:19











      • It was not the removal but the process start up overhead, what took nearly all the time. I had overlooked the -depth argument, which makes rmdir -p useless. I've changed my comment already. The 90 s was my original attempt; there's nothing surprising here.

        – maaartinus
        Mar 1 '11 at 22:20






      • 2





        I realized we can remove the rmdir command call altogether, at least with GNU find, with this command: find . -depth -type d -empty -delete

        – Christophe Drevet-Droguet
        Jan 2 '14 at 14:26

















      That's it. Instead of 90 seconds it takes 0.90 s.

      – maaartinus
      Mar 1 '11 at 22:14






      That's it. Instead of 90 seconds it takes 0.90 s.

      – maaartinus
      Mar 1 '11 at 22:14














      @maaartinus: I'm curious: do you have a similar data set where you could try without -p? I wouldn't have thought it would make a difference.

      – Gilles
      Mar 1 '11 at 22:15





      @maaartinus: I'm curious: do you have a similar data set where you could try without -p? I wouldn't have thought it would make a difference.

      – Gilles
      Mar 1 '11 at 22:15




      3




      3





      @maartinus — other little optimizations: adding -empty should work with this one (although I'm not sure exactly how much it'll gain). And very, very trivially, since you probably don't want to remove ., use -mindepth 1.

      – mattdm
      Mar 1 '11 at 22:19





      @maartinus — other little optimizations: adding -empty should work with this one (although I'm not sure exactly how much it'll gain). And very, very trivially, since you probably don't want to remove ., use -mindepth 1.

      – mattdm
      Mar 1 '11 at 22:19













      It was not the removal but the process start up overhead, what took nearly all the time. I had overlooked the -depth argument, which makes rmdir -p useless. I've changed my comment already. The 90 s was my original attempt; there's nothing surprising here.

      – maaartinus
      Mar 1 '11 at 22:20





      It was not the removal but the process start up overhead, what took nearly all the time. I had overlooked the -depth argument, which makes rmdir -p useless. I've changed my comment already. The 90 s was my original attempt; there's nothing surprising here.

      – maaartinus
      Mar 1 '11 at 22:20




      2




      2





      I realized we can remove the rmdir command call altogether, at least with GNU find, with this command: find . -depth -type d -empty -delete

      – Christophe Drevet-Droguet
      Jan 2 '14 at 14:26






      I realized we can remove the rmdir command call altogether, at least with GNU find, with this command: find . -depth -type d -empty -delete

      – Christophe Drevet-Droguet
      Jan 2 '14 at 14:26












      6














      If you just tack a -p on your rmdir, that'll work in one pass. It won't be pretty or optimal, but it should get everything. That tells rmdir to remove any non-empty parent directories of the one you're removing.



      You can save a little bit by adding the -empty test to find, so it doesn't bother with non-empty directories.






      share|improve this answer





























        6














        If you just tack a -p on your rmdir, that'll work in one pass. It won't be pretty or optimal, but it should get everything. That tells rmdir to remove any non-empty parent directories of the one you're removing.



        You can save a little bit by adding the -empty test to find, so it doesn't bother with non-empty directories.






        share|improve this answer



























          6












          6








          6







          If you just tack a -p on your rmdir, that'll work in one pass. It won't be pretty or optimal, but it should get everything. That tells rmdir to remove any non-empty parent directories of the one you're removing.



          You can save a little bit by adding the -empty test to find, so it doesn't bother with non-empty directories.






          share|improve this answer















          If you just tack a -p on your rmdir, that'll work in one pass. It won't be pretty or optimal, but it should get everything. That tells rmdir to remove any non-empty parent directories of the one you're removing.



          You can save a little bit by adding the -empty test to find, so it doesn't bother with non-empty directories.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 1 '11 at 22:13

























          answered Mar 1 '11 at 22:06









          mattdmmattdm

          29k1372117




          29k1372117





















              3














              find . -depth -type d -exec rmdir +



              is the simplest and standard compliant answer to this question.



              The other answers given here unfortunately all depend on vendor specific enhancements that do not exist on all systems.






              share|improve this answer


















              • 2





                This answer raises an error for each directory that cannot be deleted which may be less than desirable.

                – Willem van Ketwich
                Apr 13 '17 at 0:04















              3














              find . -depth -type d -exec rmdir +



              is the simplest and standard compliant answer to this question.



              The other answers given here unfortunately all depend on vendor specific enhancements that do not exist on all systems.






              share|improve this answer


















              • 2





                This answer raises an error for each directory that cannot be deleted which may be less than desirable.

                – Willem van Ketwich
                Apr 13 '17 at 0:04













              3












              3








              3







              find . -depth -type d -exec rmdir +



              is the simplest and standard compliant answer to this question.



              The other answers given here unfortunately all depend on vendor specific enhancements that do not exist on all systems.






              share|improve this answer













              find . -depth -type d -exec rmdir +



              is the simplest and standard compliant answer to this question.



              The other answers given here unfortunately all depend on vendor specific enhancements that do not exist on all systems.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 6 '15 at 12:48









              schilyschily

              10.9k31744




              10.9k31744







              • 2





                This answer raises an error for each directory that cannot be deleted which may be less than desirable.

                – Willem van Ketwich
                Apr 13 '17 at 0:04












              • 2





                This answer raises an error for each directory that cannot be deleted which may be less than desirable.

                – Willem van Ketwich
                Apr 13 '17 at 0:04







              2




              2





              This answer raises an error for each directory that cannot be deleted which may be less than desirable.

              – Willem van Ketwich
              Apr 13 '17 at 0:04





              This answer raises an error for each directory that cannot be deleted which may be less than desirable.

              – Willem van Ketwich
              Apr 13 '17 at 0:04











              0














              find . -type d -printf "%d %pn" |
              sort -nr |
              perl -pe 's/^d+s//;' |
              while read dir; do
              (rmdir "$dir" > /dev/null 2>&1);
              done



              Here's how it works:



              1. Recursively list all the directories along with their depth

              2. Sort by descending order of their depth

              3. Filter out only the directory paths

              4. Run rmdir on the list one by one





              share|improve this answer



























                0














                find . -type d -printf "%d %pn" |
                sort -nr |
                perl -pe 's/^d+s//;' |
                while read dir; do
                (rmdir "$dir" > /dev/null 2>&1);
                done



                Here's how it works:



                1. Recursively list all the directories along with their depth

                2. Sort by descending order of their depth

                3. Filter out only the directory paths

                4. Run rmdir on the list one by one





                share|improve this answer

























                  0












                  0








                  0







                  find . -type d -printf "%d %pn" |
                  sort -nr |
                  perl -pe 's/^d+s//;' |
                  while read dir; do
                  (rmdir "$dir" > /dev/null 2>&1);
                  done



                  Here's how it works:



                  1. Recursively list all the directories along with their depth

                  2. Sort by descending order of their depth

                  3. Filter out only the directory paths

                  4. Run rmdir on the list one by one





                  share|improve this answer













                  find . -type d -printf "%d %pn" |
                  sort -nr |
                  perl -pe 's/^d+s//;' |
                  while read dir; do
                  (rmdir "$dir" > /dev/null 2>&1);
                  done



                  Here's how it works:



                  1. Recursively list all the directories along with their depth

                  2. Sort by descending order of their depth

                  3. Filter out only the directory paths

                  4. Run rmdir on the list one by one






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 17 at 12:59









                  Ashish RanjanAshish Ranjan

                  62




                  62





















                      -1














                      rm -r */ command worked easily for me. rm should require -f to forcefully remove directories with files. rm -r should only remove empty directories. I'm open to why this could be wrong. This should also leave files since */ only looks at folders.






                      share|improve this answer


















                      • 1





                        I'd strongly recommend to test it thoroughly first as rm is primarily meant to remove files. While */ only matches directories, I have no idea what it does on deeper levels. I can also imagine that it works on some systems only.

                        – maaartinus
                        Jun 22 '18 at 19:30















                      -1














                      rm -r */ command worked easily for me. rm should require -f to forcefully remove directories with files. rm -r should only remove empty directories. I'm open to why this could be wrong. This should also leave files since */ only looks at folders.






                      share|improve this answer


















                      • 1





                        I'd strongly recommend to test it thoroughly first as rm is primarily meant to remove files. While */ only matches directories, I have no idea what it does on deeper levels. I can also imagine that it works on some systems only.

                        – maaartinus
                        Jun 22 '18 at 19:30













                      -1












                      -1








                      -1







                      rm -r */ command worked easily for me. rm should require -f to forcefully remove directories with files. rm -r should only remove empty directories. I'm open to why this could be wrong. This should also leave files since */ only looks at folders.






                      share|improve this answer













                      rm -r */ command worked easily for me. rm should require -f to forcefully remove directories with files. rm -r should only remove empty directories. I'm open to why this could be wrong. This should also leave files since */ only looks at folders.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jun 22 '18 at 14:36









                      libroman2libroman2

                      1




                      1







                      • 1





                        I'd strongly recommend to test it thoroughly first as rm is primarily meant to remove files. While */ only matches directories, I have no idea what it does on deeper levels. I can also imagine that it works on some systems only.

                        – maaartinus
                        Jun 22 '18 at 19:30












                      • 1





                        I'd strongly recommend to test it thoroughly first as rm is primarily meant to remove files. While */ only matches directories, I have no idea what it does on deeper levels. I can also imagine that it works on some systems only.

                        – maaartinus
                        Jun 22 '18 at 19:30







                      1




                      1





                      I'd strongly recommend to test it thoroughly first as rm is primarily meant to remove files. While */ only matches directories, I have no idea what it does on deeper levels. I can also imagine that it works on some systems only.

                      – maaartinus
                      Jun 22 '18 at 19:30





                      I'd strongly recommend to test it thoroughly first as rm is primarily meant to remove files. While */ only matches directories, I have no idea what it does on deeper levels. I can also imagine that it works on some systems only.

                      – maaartinus
                      Jun 22 '18 at 19:30

















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f8430%2fhow-to-remove-all-empty-directories-in-a-subtree%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown






                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Bahrain

                      Postfix configuration issue with fips on centos 7; mailgun relay