7

I want to cleanup a directory (and subdirectories) from each occurrance of the .py and .pyc files. I tried the following

find . -name '*pyc' -o -name '*py~' -exec rm -f {} \;

which left out all pyc files. When doing

find . -name '*pyc' -o -name '*py~'

the command finds the pyc files, which are not deleted, whatsoever. Any insights?

Alex
  • 5,700

4 Answers4

10

The -a operator (implicit between two predicates) has precedence over -o, so you need parenthesis:

find . \( -name '*pyc' -o -name '*py~' \) -a -exec rm -f {} +

(I include the -a above for demonstration purpose only, it is not needed as it is implicit). I replaced ; with + as there's probably no point running one rm per file if that can be avoided.

Anthon
  • 79,293
  • 1
    Why don't you just use -delete? – Aif Apr 04 '13 at 17:53
  • 6
    @Aif, because -delete is not a standard option. By all means, use it if your find supports it, but don't use it in scripts that are meant to be portable. – Stéphane Chazelas Apr 04 '13 at 17:56
  • find is a lot like Perl. Amazingly powerful, but write-only. – Plutor Apr 04 '13 at 22:43
  • @StephaneChazelas Oh I didn't know! I have it under OSX on both find and gnu-find, so I though "if even BSD find has it, portable it must be!". – Aif Apr 05 '13 at 10:33
10

Instead of using the -o why not just do a wildcard pattern?

find . -name '*py[c~]' -delete

or:

find . -name '*py[c~]' -exec rm -f {} +
h3rrmiller
  • 13,235
0

I know that the question it's not so new... but maybe it was enough to use

rm -f `find . -name '*.pyc' -o -name '*.py~' `
Hastur
  • 2,355
0

If you have bash 4+, you don't even need find, since globstar will give you recursive globbing:

shopt -s globstar
for f in ./**/*.py{c,~}; do rm "$f"; done

Note that shopt needs to be on its own line, rather than separated by a ; (and should be used at the very top of a script, directly below the shebang if possible).

evilsoup
  • 6,807
  • 3
  • 34
  • 40