How do I remove all .pyc files from a project?
Asked Answered
T

26

743

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?

Trevethick answered 24/4, 2009 at 11:51 Comment(2)
It doesn't work because in UNIX, globs are expanded by the shell, not by the program being run. If you have a.pyc and b.pyc in the current directory, and directories foo and bar, rm will be called with arguments [-r, a.pyc, b.pyc].Thumbsdown
if you are worrying about pushing your code to other people, you can just add it to the .gitignore **/*.pyc then you won't have to worry about it againHedge
I
1294
find . -name "*.pyc" -exec rm -f {} \;
Infatuate answered 24/4, 2009 at 11:55 Comment(10)
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.Venepuncture
Find has a builtin "-delete" action, so you could do just find . -name \*.pyc -deleteCollision
Most importantly, if this is a dev machine, you can set PYTHONDONTWRITEBYTECODE=True, and you'll never need to do this again. See: this answer.Urbanist
You are not quoting {}. What would happen if accidentally word-split and deleted an intermediate path which happens to be called like a fragment of the path you found?Dinitrobenzene
in my .bashrc: alias rmPyCrap="find . -name \*.pyc -delete && find . -type d -name __pycache__ -delete"Twentytwo
-delete is not part of the POSIX specification, and not guaranteed to exist in all implementations of find.Prairial
If you are scared - which might be good - make a first pass with -exec echo {}, or - if you are very scared - use rm -i {} which ask you each time or rm - v {} so you see what you delete.Plectrum
Just confirming this worked for me on Mac OSX mavericks.Hirundine
Where can I set PYTHONDONTWRITEBYTECODE? Is there some kind of file I can edit?Leucocratic
when deleting many files, this command may have an issue.. especially when memory on the machine that you are running the command on is low. Andy Baker's answer is much better.Heterogenetic
C
1071

find . -name '*.pyc' -type f -delete

Surely the simplest.

Corymb answered 29/5, 2009 at 11:37 Comment(8)
If your version of find supports -delete; it is not part of the POSIX standard.Prairial
This ignores .pyo files and __pycache__ directories. See my answer.Sepulture
I used the code from the accepted answer and it worked, but these commands are shorter and simpleHydrography
@MattCaldwell Is rm not sufficient (drop -f)?Partan
@RuddZwolinski it doesn't feel safer when you think you know it by heart, don't, omit the -name and delete your entire env!Holtorf
-name '*.py?' to include .pyo, .pyc,...Ominous
MAKE SURE -delete is the last thing in the command. I accidentally put -delete right after the find. It deleted everything!Anarchism
make sure about what you are going to do here, if you are inside the python virtual environment and if you executes this command it will remove the entire .pyc in the virtual environment as well.Tattered
S
96

Add to your ~/.bashrc:

pyclean () {
        find . -type f -name "*.py[co]" -delete
        find . -type d -name "__pycache__" -delete
}

This removes all .pyc and .pyo files, and __pycache__ directories. It's also very fast.

Usage is simply:

$ cd /path/to/directory
$ pyclean
Sepulture answered 7/4, 2014 at 15:2 Comment(1)
find . -type d -name "__pycache__" -delete will often give a warning about a missing path because apparently the contents will be added to the queue before the folder is deleted. 2>/dev/null should fix that.Subscapular
F
88

In current version of debian you have pyclean script which is in python-minimal package.

Usage is simple:

pyclean .
Freezer answered 2/12, 2012 at 11:18 Comment(3)
It's worth noting that pyclean appears to only delete .pyc files for which there is a corresponding .py file (at least on my system - ubuntu 12.10.) This means it's not very helpful in situations where a source file has been deleted and you want to clean up the leftover .pyc files.Schluter
@holms pyclean (and now py3clean) originate in a Debian package, and thus aren’t in RHEL.Partan
The pyclean command is now available as a Python package installable from PyPI, which work cross-platform (including RHEL, macOS and Windows). It deletes any .pyc file w/o special preference as of today.Mehalek
M
53

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

rm **/*.pyc

Note that */*.pyc selects all .pyc files in the immediate first-level subdirectories while **/*.pyc recursively scans the whole directory tree. As an example, foo/bar/qux.pyc will be deleted by rm **/*.pyc but not by */*.pyc.

The globstar shell options must be enabled. To enable globstar:

shopt -s globstar

and to check its status:

shopt globstar
Macrobiotic answered 25/4, 2009 at 17:36 Comment(3)
What's the difference in running rm **/*.pyc vs rm */*.pyc? (The latter seemed to work for me locally.)Eisenstark
@TaylorEdmiston rm */*.pyc will delete all .pyc files in all subdirectories of depth 1. rm **/*.pyc will delete all .pyc files in all subdirectories of depth 0+Halberd
@AdamStewart Thanks for adding this. For others stumbling on this thread, the issue I was experiencing was that Apple's bash shipped with OS X doesn't include globstar (so ** acts as * when run instead and running shopt globstar throws an error).Eisenstark
T
35

For windows users:

del /S *.pyc
Tyre answered 23/10, 2015 at 13:47 Comment(2)
Putting this in a batch script makes things super easy. Thanks.Mohair
And if you are on Powershell, this can be used with "cmd" -> Run command -> "exit".Twitch
P
30

I used to use an alias for that:

$ which pycclean

pycclean is aliased to `find . -name "*.pyc" | xargs -I {} rm -v "{}"'
Pansy answered 25/4, 2009 at 17:19 Comment(5)
In current debian it is pyclean.Freezer
This doesn't deal with whitespace in filenames well. You should use find -print0 and xargs -0 instead.Hertz
Why would you want to have python code with spaces in the file/folder names? Is that syntactically legal?Hoofbeat
@CoreDumpError, yes, in fact on Windows Python installs to a directory with spaces ("Program Files").Obligatory
The python interpreter may install there by default, but it's hardly a good place to put your code. Plus, you certainly wouldn't want the Program Files folder to be part of your package structure, which is why I was wary about syntax.Hoofbeat
C
18
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 file names containing spaces, and even a file name 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.

Cly answered 25/4, 2009 at 17:12 Comment(0)
W
16
$ find . -name '*.pyc' -delete

This is faster than

$ find . -name "*.pyc" -exec rm -rf {} \;
Wearable answered 14/7, 2014 at 0:49 Comment(0)
N
15

Further, people usually want to remove all *.pyc, *.pyo files and __pycache__ directories recursively in the current directory.

Command:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
Nope answered 14/4, 2017 at 2:28 Comment(2)
This is a good answer, but a plain Python solution would be cross-platform and hence preferable. While, personally, I don't care about Windows probably half of the Python population lives on Windows -- and find, grep and friends don't work there.Mehalek
They do if you install the tooling. I'd recommend every windows CLI user do so to ease cross-compat: superuser.com/questions/168202/…Devland
P
11

Django Extension

Note: This answer is very specific to Django project that have already been using Django Extension.

python manage.py clean_pyc

The implementation can be viewed in its source code.

Perfoliate answered 13/12, 2015 at 17:46 Comment(0)
S
8

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

rm `find . -name *.pyc`
Spacial answered 29/5, 2009 at 11:48 Comment(1)
This has the slight drawback of failing if there are too many matches, as there will be too many arguments to pass to rm.Prairial
C
7

full recursive

ll **/**/*.pyc
rm **/**/*.pyc
Chlorobenzene answered 3/9, 2012 at 19:42 Comment(3)
Interesting, how does this compare to Andy and Bill's answers?Bireme
One set of ** is redundant, and as in d0k's answer, you must have globstar enabled in bash 4+ for this to work as intended. i.e. do shopt -s globstar or have that in one of your sourced bash . files.Oberg
Also ll is commonly aliased to something like ls -l, but isn't really a command or portable. So, to recursively list all .pyc files in ., you should instead do something like echo **/*.pyc with globstar enabledOberg
B
5

There is the pyclean package on PyPI and Anaconda, which is easy to use and cross-platform.

python -m pip install pyclean

You then just need to run a simple command to clean all __pycache__ folders and *.pyc files in current dir:

pyclean .

It also has additional options to delete various artifacts from running builds and tests.

Brandish answered 27/2, 2021 at 4:42 Comment(0)
C
4

if you don't want .pyc anymore you can use this single line in a terminal:

export PYTHONDONTWRITEBYTECODE=1

if you change your mind:

unset PYTHONDONTWRITEBYTECODE
Cumulate answered 12/5, 2018 at 8:27 Comment(0)
B
3

First run:

find . -type f -name "*.py[c|o]" -exec rm -f {} +

Then add:

export PYTHONDONTWRITEBYTECODE=1

To ~/.profile

Bukhara answered 31/10, 2014 at 0:10 Comment(0)
V
2

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.

Venepuncture answered 24/4, 2009 at 11:58 Comment(3)
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)Trevethick
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...Venepuncture
That's an awful antipattern (and a very common one too, I wish it could disappear): it breaks with filenames containing spaces or glob characters. And it misses the point of find with its -exec predicate: find . -name '*.pyc' -exec rm {} + (nicer, shorter, safer, robust, more efficient).Walls
A
2
find . -name "*.pyc"|xargs rm -rf
Almetaalmighty answered 20/11, 2014 at 12:11 Comment(0)
Y
2

If you want to delete all the .pyc files from the project folder.

First, you have

cd <path/to/the/folder>

then find all the .pyc file and delete.

find . -name \*.pyc -delete
Yunyunfei answered 27/10, 2019 at 6:44 Comment(0)
T
1

You can run find . -name "*.pyc" -type f -delete.

But use it with precaution. Run first find . -name "*.pyc" -type f to see exactly which files you will remove.

In addition, make sure that -delete is the last argument in your command. If you put it before the -name *.pyc argument, it will delete everything.

Twosome answered 11/10, 2018 at 15:19 Comment(0)
L
1

To delete all the python compiled files in current directory.

find . -name "__pycache__"|xargs rm -rf
find . -name "*.pyc"|xargs rm -rf
Larimer answered 17/2, 2021 at 11:19 Comment(0)
C
0

If you want remove all *.pyc files and __pycache__ directories recursively in the current directory:

  • with python:
import os

os.popen('find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf')
  • or manually with terminal or cmd:
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
Chromaticity answered 25/1, 2021 at 12:58 Comment(0)
E
0

py3clean works for me!

cd /usr/local/lib/python3.9
sudo py3clean -v .
Epigraphic answered 20/7, 2022 at 12:49 Comment(0)
P
0

Had to add a few ignore params on M1:

pyclean --verbose . --ignore "Library",".Trash"  
Possess answered 3/1, 2023 at 17:27 Comment(0)
S
0

DEL /F /S /Q "Z:\aaa\*.pyc"
use cmd, or save in bat file, in window

Spinous answered 6/4, 2023 at 15:39 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Emotionalism
D
0

In windows where find wont work. Here is a python function which can be run in ipython or python default interpretor or run as a script. Just putting for easy accessibility for some one.

from pathlib import Path
from os import remove

def remove_files(pth, filetype = "*.pyc"):
   pth = Path(pth)
   for file in pth.glob(f"**/{filetype}"):
   remove(file)

You can call the function as:

target_folder = <path to clean>
remove_files(target_folder)
Drice answered 15/2 at 3:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.