35

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.

70

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.)

  • 1
    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
  • watch out for the last command, somehow it deleted some files. the xargs command worked well. – Henrique de Sousa Sep 20 '16 at 10:14
23
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.

  • 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
  • 3
    you could use + instead of \; to pass more than one directory at a time. – jfs 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
7

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

5

You can also use -exec option

find . -name test -exec rm {} \;
3

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/
2

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

find . -name test -delete

which is easier to remember.

2

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

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.