Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have many directories named "test" and I would like to remove them.

I know how to find them and print them using:

find . -name test -print

Now, how to do I remove the directories?


Please note that I have files in the directory as well and they must be removed as well.

share|improve this question

migrated from stackoverflow.com May 31 '13 at 23:03

This question came from our site for professional and enthusiast programmers.

up vote 49 down vote accepted

xargs does all the magic:

find . -name test -type d -print0|xargs -0 rm -r --

xargs executes the command passed as parameters, with the arguments passed to stdin.

This is using rm -r to delete the directory and all its children.

The -- denotes the end of the arguments, to avoid a path starting with - from being treated as an argument.

-print0 tells find to print \0 characters instead of newlines; and -0 tells xargs to treat only \0 as argument separator.

This is calling rm with many directories at once, avoiding the overhead of calling rm separately for each directory.


As an alternative, find can also run a command for each selected file:

find . -name test -type d -exec rm -r {} \;

And this one, with better performance, since it will call rm with multiple directories at once:

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

(Note the + at the end; this one is equivalent to the xargs solution.)

share|improve this answer
    
Excellent answer, especially the + in find. I had no idea, definitely wished I'd had known that long ago. – Scott Jun 19 '13 at 22:18
find /path/to/dir -name "test" -type d -delete
  • -name: looks for the name passed. You can use -regex for providing names based on regular expressions

  • -type: looks for file types. d only looks for directories

  • -delete: action which deletes the list found.

Alternatively:

find /path/to/dir -name "test" -type d -exec rm -rf {} \;

As J.F. Sebastian stated in the comments:

You could use + instead of \; to pass more than one directory at a time.

share|improve this answer
1  
Sorry, I forgot mention that these directories may have files. I couldn't delete some of them because of "find: cannot delete `./start': Directory not empty" error – garbage collection May 31 '13 at 19:43
    
@garbagecollection I added an update. – jaypal singh May 31 '13 at 19:50
2  
you could use + instead of \; to pass more than one directory at a time. – J.F. Sebastian May 31 '13 at 19:55
    
Thanks @J.F.Sebastian Good point. I will add it to the answer. – jaypal singh May 31 '13 at 20:03

yet another way to do this is

find . -name test -exec rm -R "{}" \;

A helpfull link on find : http://www.softpanorama.info/Tools/Find/using_exec_option_and_xargs_in_find.shtml

share|improve this answer

You can also use -exec option

find . -name test -exec rm {} \;
share|improve this answer

Assume you are using gnu find, you can use -delete option:

find . -name test -delete

which is easier to remember.

share|improve this answer

As another answer points out, you can attempt to find all directories with the name test and delete them

find -name "test" -type d -delete

I ran into some issues with cross compatibility on Mac, so I used this equivalent command:

find -path "*/test" -type d -delete
  • -path: looks for a pattern in the fully qualified filename.

In either case however, if any of the directories named test have files in them, find will complain that the Directory is not empty, and will fail to remove the directory.

If you intended to delete all of the files including the test directory, then we can use the same trick to delete all of the files inside directories named test first.

find -path "*/test/*" -delete

The pattern: "*/test/*", will ensure we only delete files inside a directory named /test/. Once the directories are empty, we can go ahead and delete the directories using the first command:

find -path "*/test" -type d -delete

Example:

$ tree
.
├── mytest
│   └── test
│       └── blah.txt
├── test
│   ├── bar.jpg
│   └── dir
│       └── bar.bak
└── testdir
    └── baz.c

5 directories, 4 files

$ find -path "*/test" -type d -delete
$ tree
.
├── mytest
│   └── test
├── test
└── testdir
    └── baz.c

4 directories, 1 file

$ find -name "test" -type d -delete
$ tree
.
├── mytest
└── testdir
    └── baz.c

2 directories, 1 file
share|improve this answer

Assuming bash 4+

shopt -s globstar
rm -r ./**/test/

The trailing slash means that it will only match directories. Test is beforehand with:

printf '%s\n' ./**/test/
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .