tags:

views:

1575

answers:

7

I've renamed some files in a fairly large project and want to remove the .pyc files they've left behind. I tried the bash script:

 rm -r *.pyc

But that doesn't recurse through the folders as I thought it would, what am I doing wrong?

Thanks

+21  A: 
find . -name "*.pyc" -exec rm -rf {} \;
Bill the Lizard
Nothing appears to be happening.
Teifion
Perhaps it should be -name "*.pyc" instead of -name ".pyc"? That worked for me.
Chris Lutz
Thanks Chris, that fixed it. I deleted *.svn in a script I use all the time and replaced it with .pyc originally. My mistake.
Bill the Lizard
Accepted this one over the other one (which was previously accepted) as it's shorter and now works :)
Teifion
I tested both of these. The directories were probably too small to be significant, but this came out faster than mine, which is what I expected since mine has to assemble the list and then iterate through it, while yours removes each item as it is found.
Chris Lutz
Find has a builtin "-delete" action, so you could do just `find . -name \*.pyc -delete`
Christoffer
+1  A: 

rm -r recurses into directories, but only the directories you give to rm. It will also delete those directories. One solution is:

for i in $( find . -name *.pyc )
do
  rm $i
done

find will find all *.pyc files recursively in the current directory, and the for loop will iterate through the list of files found, removing each one.

Chris Lutz
This one works though I have to put it in a .sh file and run that (which is fine by me, I'll be using this command more than once)
Teifion
I believe putting it all on one line separated with ';'s should let you run it at the shell. But when I type that in bash, bash waits for the "done" at the end to execute anything...
Chris Lutz
+4  A: 
find . -name '*.pyc' -print0 | xargs -0 rm

The find recursively looks for *.pyc files. The xargs takes that list of names and sends it to rm. The -print0 and the -0 tell the two commands to seperate the filenames with null characters. This allows it to work correctly on files containing spaces, and even a file containing a new line.

The solution with -exec works, but it spins up a new copy of rm for every file. On a slow system or with a great many files, that'll take too long.

You could also add a couple more args:

find . -iname '*.pyc' -print0 | xargs -0 --no-run-if-empty  rm

iname adds case insensitivity, like *.PYC . The no-run-if-empty keeps you from getting an error from rm if you have no such files.

Ron Romero
A: 
$ which pycclean

pycclean is aliased to `find . -name "*.pyc" | xargs -I {} rm -v "{}"'
The MYYN
+4  A: 

if you're using bash >=4.0 (or zsh)

rm **/*.pyc

(the globstar shell options must be enabled)

d0k
+14  A: 

find . -name '*.pyc' -delete

Surely the simplest?

andybak
Didn't know about -delete : +1
yangyang
This one makes the most sense, thanks! :)
PKKid
+1. This command feels much safer than the currently accepted one by Bill the Lizard. Any command with `rm -rf` in it is a little scary. :)
Rudd Zwolinski
+2  A: 

Just to throw another variant into the mix, you can also use backquotes like this:

rm `find . -name *.pyc`
Clint Miller
Bash is so versatile, and amazing. :)
PKKid