How do I recursively delete directories with wildcard?

find is very useful for selectively performing actions on a whole tree.

find . -type f -name ".Apple*" -delete

Here, the -type f makes sure it's a file, not a directory, and may not be exactly what you want since it will also skip symlinks, sockets and other things. You can use ! -type d, which literally means not directories, but then you might also delete character and block devices. I'd suggest looking at the -type predicate on the man page for find.

To do it strictly with a wildcard, you need advanced shell support. Bash v4 has the globstar option, which lets you recursively match subdirectories using **. zsh and ksh also support this pattern. Using that, you can do rm -rf **/.Apple*. This is not POSIX-standard, and not very portable, so I would avoid using it in a script, but for a one-time interactive shell action, it's fine.


I ran into problems using find with -delete due to the intentional behavior of find (i.e. refusing to delete if the path starts with ./, which they do in my case) as stated in its man page:

 -delete

Delete found files and/or directories. Always returns true. This executes from the current working directory as find recurses down the tree. It will not attempt to delete a filename with a "/" character in its pathname relative to "." for security reasons.
Depth-first traversal processing is implied by this option.
Following symlinks is incompatible with this option.

Instead, I was able to just do

find . -type d -name 'received_*_output' -exec rm -r {} +

For your case, it seems that quoting the glob (asterisk, *) was the solution, but I wanted to provide my answer in case anyone else had the similar problem.

NOTE: Previously, my answer was to do the following, but @Wildcard pointed out the security flaws in doing that in the comments.

find . -type d -name 'received_*_output' | xargs rm -r