How do I remove all *.foo in a directory tree?

rm -r *.foo

does not work.

I could try a loop, but that needs recursive expansion:

for x in */*/.../*.foo
    do rm $x

Which is not possible either.


4 Answers 4


You can use find:

find -name '*.foo' -delete
  • Would this work? shouldn't it be find . -name?
    – Rob
    Dec 23, 2013 at 19:24
  • 1
    @Rob, man find: If no paths are given, the current directory is used.
    – cYrus
    Dec 23, 2013 at 19:50
  • @cYrus find is indeed really powerful. It lacks two actions that probably is easy to implement: -callso youraction.so and -cfunc foo.c . The shared object only needs to export a function void doIt(const char* path). That would be really powerful.
    – user877329
    Dec 24, 2013 at 9:22
  • @user877329, there's the -exec action that can be used for that purpose.
    – cYrus
    Dec 24, 2013 at 11:25
  • 1
    @user877329, I see your point, but in my experience these tools are good for getting things done quickly and easily, but if you need to do it right then you often have to start developing your own tool.
    – cYrus
    Dec 24, 2013 at 11:47

Assuming you have a fairly recent version of bash:

shopt -s globstar
rm -- **/*.foo
  • 2
    Same with zsh, but you don't need the shopt. Dec 23, 2013 at 17:44

You could try using find:

find /dir/path -name *.foo -exec rm -f {} \;
  • 3
    Shouldn't *.foo be '*.foo'?
    – Timtech
    Dec 23, 2013 at 15:09

One of the easiest solutions would be to use the find command with the exec parameter:

find /path/where/to/start/search -type f -name "*.foo" -exec rm {} \;

This will look for all files named *.foo and perform rm {filename} for each one.

If you have lots of files, use of the xargs command may be faster:

find /path/where/to/start/search -type f -name "*.foo" | xargs rm 

This will find all files, and will put the file names behind the rm command up until the max length of a command your distro/shell will support, so when run it'll to this:

rm dir1/file1.foo dir1/file2.foo dir1/file3.foo 

As you can imagine now the rm binary needs to be started much less, making this a faster option.

  • 2
    Just to be safe, I'd suggest replacing | xargs with -print0 | xargs -0. By default, xargs splits its input on any whitespace, which could produce unwanted results if any file or directory names had spaces in them. The extra switches make find and xmarks use null bytes, which are not allowed in filenames, as separators instead. Dec 23, 2013 at 13:49
  • I'd just use the -delete flag.
    – Rob
    Dec 23, 2013 at 19:25
  • Not all versions of find include the -delete flag (for example on Solaris <11), so using xargs or -exec is more universal.
    – mtak
    Dec 24, 2013 at 11:29

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.