I issue the following command to find the .svn directories:

find . -name ".svn"

That gives me the following results:


How could I process all these lines with rm -fr in order to delete the directories and their content?

  • 4
    GNU find has the -delete option. – Marco Sep 9 '13 at 8:49
  • 5
    Or you can add -exec rm -r "{}" \; to the end of the find - be careful when using rm -r! :) – Drav Sloan Sep 9 '13 at 8:52
  • 13
    @Marco The delete option does not seem to work on directories. – Arnaud Sep 9 '13 at 9:01
  • @SuperChafouin It works perfectly well here on files and directories. The point is that it only deletes emtpy directories and when you specify -name ".svn" it matches only the .svn directory itself and not the files located in the .svn directory. – Marco Sep 9 '13 at 9:22
  • 1
    @SuperChafouin but will not work for paths with spaces in them (hence using -exec with quoted "{}"). – Drav Sloan Sep 9 '13 at 9:55

Find can execute arguments with the -exec option for each match it finds. It is a recommended mechanism because you can handle paths with spaces/newlines and other characters in them correctly. You will have to delete the contents of the directory before you can remove the directory itself, so use -r with the rm command to achieve this.

For your example you can issue:

find . -name ".svn" -exec rm -r "{}" \;

You can also tell find to just find directories named .svn by adding a -type d check:

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

Warning Use rm -r with caution it deletes the folder and all its contents.

If you want to delete just empty directories as well as directories that contain only empty directories, find can do that itself with -delete and -empty:

find . -name ".svn" -type d -empty -delete
| improve this answer | |
  • 31
    I have seen advice to always run -type after -name in find commands, since calls to stat to get the type are expensive. I just tried it myself on a fairly large bunch of files, and it seems to be true: running find . -name 'foo' -type d took 19 secs, while find . -type d -name 'foo' took 32 secs. So about 50% longer time to run -type first. – spinup Mar 16 '15 at 16:37
  • 10
    i've been using this command for years, but on Mac now i get errors saying those directories do not exist. Even though it does delete them. I never saw messages before. – chovy Dec 23 '15 at 8:51
  • 1
    Same as @chovy. Is there a way to get rid of these messages? – Clément Apr 23 '16 at 15:32
  • 2
    @chovy @clément That is because find wants to see in that folder for other matches, while it's removing the folder at the same time. ~I don't know yet how to fix this.~ Dirty fix: find . -name "folder-to-delete" -print0 | xargs -r0 -- rm -r – Charlie Jul 20 '16 at 12:02
  • 7
    @chovy @Clément I think the -depth argument fixes this: find . -depth -name ".svn" -type d -exec rm -r "{}" \; – gimboland Jul 27 '16 at 7:57

Here is a portable still faster than the accepted answer way.

Using a + instead of a semicolon as find command terminator is optimizing the CPU usage. That can be significant if you have a lot of .svn sub-directories:

find . -name .svn -type d -exec rm -rf {} +

Note also that you never1 need to quote the curly braces here.

1 Unless you use the fish shell (this might have been fixed since I wrote this reply).

| improve this answer | |
  • 5
    What's difference between + and semicolon? Why we don't use curly braces? – Shicheng Guo Jan 4 '17 at 19:25
  • 2
    @ShichengGuo With the semicolon, there will be one rm command per directory found, with the + a single rm command will process all directories found (or at least a very large number of them.) I don't get your second question, curly braces are used here. – jlliagre Jan 4 '17 at 20:13
  • I think @ShichengGuo means why don't we need to quote the curly braces here (@jlliagre wrote that we never need to quote them). I can't find a reference now, but I understand it's because find will automatically escape the paths replaced for {}. – Quinn Comendant Mar 8 '17 at 6:47
  • The answer and the question are not quite right on what + does. If many files are found then ';' would give 'command line too long' error. + splits the files found in batches which are less than max allowed command line length and runs the command for each batch. – gaoithe Mar 22 '17 at 11:56
  • 1
    @gaoithe I did rollback you edit which replaced a correct statement with an incorrect one. Using + does reduce CPU usage, Using ; does not lead to a command too long error. – jlliagre Mar 22 '17 at 12:26

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

find . -name test -delete

which is easier to remember.

| improve this answer | |
  • Consider expanding your post with an explanation of the command (or documentation to back up your solution). Often one (or two) line answers are not the most illuminating. – HalosGhost Aug 10 '14 at 23:02
  • 110
    This doesn't work on non-empty directories. – belacqua Dec 16 '14 at 20:47
  • 2
    also works on Mac OS X – draw Mar 29 '16 at 3:11
  • This does not work for non-empty folder but it's the easier & safer solution – RousseauAlexandre Feb 7 '18 at 16:01
  • 1
    The options order is very important, find will execute them in order so, -delete have to be the last one – Jose Ignacio Centeno Mar 6 '18 at 7:25

On my computer when I use:

find . \( -name dirname -type d \) -exec rm -r '{}' ';'

The directories are deleted but I get the error:

find: ‘./dirname’: No such file or directory

for each directory.

My directories aren't empty, so the -delete option won't work for me. I found the reason for this behavior here:

  1. find takes (not necessarily) the first entry in the ./ directory. this would be e.g. dir.1/
  2. it compares it to the pattern 'dir.?'. does it match? yes.
  3. find executes "rm -r dir.1".
  4. find tries to enter dir.1/ to find the pattern within the directory. it doesn't know anything about the exec command.
  5. it doesn't find dir.1/ anymore. returns ENOENT (look at the strace output)

I used this instead to work around:

rm -r `find . -name dirname -type d`

Keep in mind that find will still try to recurse into directories named dirname, which isn't really necessary and will take some additional time. Depending on your directory structure, you might be able to work around this with the --depth find option. In addition, if you have a directory structure like dirname/foo/dirname you will get "No such file or directory" errors from rm. To suppress the errors you can redirect stderr to /dev/null or use the -f (force) flag with rm.

| improve this answer | |
  • 3
    Bad idea: file name with spaces will cause all sorts of horrible issues – Clément Apr 23 '16 at 15:31
  • 3
    For future readers: find . -name "to-delete" -print0 | xargs -r0 -- rm -r is a failproof version which doesn't crash on spaces – Charlie Jul 20 '16 at 12:08
  • 3
    See unix.stackexchange.com/a/115869/8257 you need to add -prune. – Mapio Jan 29 '17 at 1:59
  • 1
    Add -prune to avoid the "No such file or directory" error. – Julien Carsique Feb 24 '17 at 16:25

A faster way to do this is:

find . -name ".svn" -type d -prune -exec rm -rf '{}' '+'

In case you have ".svn" inside another ".svn".

| improve this answer | |
  • That's not very useful if you want to find the directories to delete with the sub-directories. – Alexis Wilke Aug 1 '18 at 7:47
  • using -prune is the most accurate way. Thanks! – alexandre1985 Jun 27 at 15:10

Bash specific solution:

shopt -s globstar
rm -r **/.svn
shopt -u globstar #optional. this will disable globstar expansion
| improve this answer | |
  • 3
    Note for command line expansion of globs that match many files, there is a limit to the number of files you can match with this mechanism. Going over this limit will result in bash: /bin/rm: Argument list too long – Drav Sloan Sep 9 '13 at 10:06
  • 1
    @DravSloan is correct, but that limit is in the hundreds of thousands of files. It's something to bear in mind, but probably won't be a problem for most people. – evilsoup Sep 9 '13 at 10:26

I've found that the -delete action does work nicely with the -path test. For instance, the following ought to work on the original posters problem:

find . -path '*/.svn*' -delete

Note that in addition to deleting '.svn' directories (and their contents), this will also delete any files or directories whose names start with '.svn'. For example, if you used -path '*/.git*' it would also delete '.gitignore' and '.gitattribute' in addition to '.git/'. To avoid that, and just delete directories with that exact name use:

find . -path '*/.svn/*' -or -name '.svn' -delete

Note the slash after .svn. This will first find, and delete, all the files under '.svn', then delete the .svn directory itself.

| improve this answer | |
  • Are you sure? -delete implies -depth, and it sure deletes non-empty directories on my system. – Magnus Dec 20 '17 at 13:56
  • Retested and it works. Maybe it was just typo which I've corrected. – kenorb Jan 5 '18 at 22:23
  • I also tried this approach and it worked - the directories were deleted. – Allan Apr 6 '18 at 8:38

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.