Shell – How to Remove All Sub-Directories from a Directory

command linedirectoryrmshellwildcards

This question is kind of a phase II to the first question I posted at here

I have a directory that contains a bunch of sub-directories, .zip files, and other random files not contained within a sub-directory.

I'd like a command line script to remove all sub-directories from within the parent directory, but keep all zip files and loose files that don't belong to any sub-directories. All of the sub-directories have content, so I believe I'd need to force their deletion with the -f command.

So basically, a command that looks inside the parent directory (or the current directory), deletes all folders from within it, but keeps all other content and files that are not a folder or contained within a folder.

I understand that deleting items from the command line requires special care, but I have already taken all necessary precautions to back up remotely.

Best Answer

In BASH you can use the trailing slash (I think it should work in any POSIX shell):

rm -R -- */

Note the -- which separates options from arguments and allows one to remove entries starting with a hyphen - otherwise after expansion by the shell the entry name would be interpreted as an option by rm (the same holds for many other command line utilities).

Add the -f option if you don't want to be prompted for confirmation when deleting non-writeable files.

Note that by default, hidden directories (those whose name starts with .) will be left alone.

An important caveat: the expansion of */ will also include symlinks that eventually resolve to files of type directory. And depending on the rm implementation, rm -R -- thelink/ will either just delete the symlink, or (in most of them) delete the content of the linked directory recursively but not that directory itself nor the symlink.

If using zsh, a better approach would be to use a glob qualifier to select files of type directory only:

rm -R -- *(/) # or *(D/) to include hidden ones

or:

rm -R -- *(-/)

to include symlinks to directories (but because, this time, the expansion doesn't have trailing /s, it's the symlink only that is removed with all rm implementations).

With bash, AT&T ksh, yash or zsh you can do:

set -- */
rm -R -- "${@%/}"

to strip the trailing /.

Related Question