0

I need to remove a target folder in all subfolders.

  • What have you tried? – Nasir Riley Nov 22 '19 at 8:29
  • Expecting it should be easy like rm -r target but no luck yet. – kio21 Nov 22 '19 at 8:31
  • Looks like I'm enough with one level removal rm -r **/target – kio21 Nov 22 '19 at 8:44
1

EDIT:

based on comments on this question, it is better to fully use the wide functionality of the find command and skip piping altogether (also telling find not to descend into directory it's going to ask rm to delete):

find . -type d -name target -prune -exec rm -r {} +

Should work fine for you.

Sorry all, for posting an unsatisfying answer. Your feedback has been very informative.


Original answer:

With a little google-fu to list all subdirectories and pipe to rm:

find . -type d | grep -E '/target$' | xargs rm -r

Should work. Check whether find . -type d | grep -E '/target$' gives the expected output before you remove the folders! Better be save than sorry.

  • 1
    This would delete any directory that contains the string target in its name! For example, not-target. – Kusalananda Nov 22 '19 at 8:46
  • Thank you so much @Kusalananda! I totally forgot about that.. The answer is now modified to use regular expressions and check for an end-of-line. – Pudding Nov 22 '19 at 8:51
  • Why not use -name target with find? – Kusalananda Nov 22 '19 at 8:53
  • And -exec, still with find... – Stephen Kitt Nov 22 '19 at 8:54
2

If you know you won't have more than a few thousands of these target directories, you may set the globstar and dotglob shell options in bash with

shopt -s globstar dotglob

and then use

rm -rf ./**/target/

This would delete any directory called target in or below the current directory. The slash at the end is crucial as the pattern may otherwise match things that are not directories.

The ** pattern is enabled by setting the globstar shell option, and matches "recursively" down into subdirectories. Since dotglob is also set, this would find directories called target beneath hidden subdirectories as well (just like find would do).

On macOS, the default bash is too old to support the globstar shell option, so there you may want to install the most recent bash using Homebrew, or switch to zsh (which currently is the default shell for new macOS user accounts).

With zsh, you'd do this operation with

rm -rf ./**/target(/D)

Where (/D) means "match only directories and include hidden directories". The ** glob is enabled by default in zsh.


With find:

find . -depth -type d -name target -exec rm -rf {} +

This would find all the target directories located in or below the current directory, and then call rm -rf with as many as possible of these at a time to delete them. The -depth option makes find do a depth-first search (we want this to avoid trying to search directories that we've just deleted).

This would be the command you would use if you were using sh as the shell (which does not have **), or if you have many thousands of such directories.

Even if you have a large number of target directories, you should still be able to delete them one by one with

for dirpath in ./**/target/; do
    rm -rf "$dirpath"
done

although this would be slower than using find since you are calling rm once for every directory.

  • As the poster specified the tag macos, there is a good chance that globstar doesn't work for them. Nonetheless a very full and interesting answer. Thank you! – Pudding Nov 22 '19 at 9:32
  • @Pudding Thanks for the heads-up about that. I have modified the answer. – Kusalananda Nov 22 '19 at 9:36

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.