Find and delete all the directories named "test" in linux

36

26

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.

garbage collection

Posted 2013-05-31T19:36:39.200

Reputation: 495

Answers

71

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

Arnaud Le Blanc

Posted 2013-05-31T19:36:39.200

Reputation: 979

watch out for the last command, somehow it deleted some files. the xargs command worked well. – Henrique de Sousa – 2016-09-20T10:14:38.290

1Excellent answer, especially the + in find. I had no idea, definitely wished I'd had known that long ago. – Scott – 2013-06-19T22:18:07.600

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.

jaypal singh

Posted 2013-05-31T19:36:39.200

Reputation: 2 134

1Sorry, 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 – 2013-05-31T19:43:34.810

@garbagecollection I added an update. – jaypal singh – 2013-05-31T19:50:00.583

3you could use + instead of \; to pass more than one directory at a time. – jfs – 2013-05-31T19:55:18.290

Thanks @J.F.Sebastian Good point. I will add it to the answer. – jaypal singh – 2013-05-31T20:03:53.027

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

maazza

Posted 2013-05-31T19:36:39.200

Reputation: 336

5

You can also use -exec option

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

sethi

Posted 2013-05-31T19:36:39.200

Reputation: 151

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/

evilsoup

Posted 2013-05-31T19:36:39.200

Reputation: 10 085

2

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

find . -name test -delete

which is easier to remember.

Chun Yang

Posted 2013-05-31T19:36:39.200

Reputation: 121

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

Karl

Posted 2013-05-31T19:36:39.200

Reputation: 36