Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
done

Which is not possible either.

share|improve this question
    
How can I make chown work recursively? is basically the same question, except with chown instead of rm. –  Ilmari Karonen Dec 23 '13 at 13:46

4 Answers 4

up vote 9 down vote accepted

You can use find:

find -name '*.foo' -delete
share|improve this answer
    
Would this work? shouldn't it be find . -name? –  Rob Dec 23 '13 at 19:24
1  
@Rob, man find: If no paths are given, the current directory is used. –  cYrus Dec 23 '13 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 '13 at 9:22
    
@user877329, there's the -exec action that can be used for that purpose. –  cYrus Dec 24 '13 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 '13 at 11:47

Assuming you have a fairly recent version of bash:

shopt -s globstar
rm -- **/*.foo
share|improve this answer
2  
Same with zsh, but you don't need the shopt. –  Stéphane Gimenez Dec 23 '13 at 17:44

You could try using find:

find /dir/path -name *.foo -exec rm -f {} \;
share|improve this answer
3  
Shouldn't *.foo be '*.foo'? –  Timtech Dec 23 '13 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.

share|improve this answer
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. –  Ilmari Karonen Dec 23 '13 at 13:49
    
I'd just use the -delete flag. –  Rob Dec 23 '13 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 '13 at 11:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.