ChatGPT解决这个技术问题 Extra ChatGPT

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

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?

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].
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 again

M
Mark Amery
find . -name "*.pyc" -exec rm -f {} \;

Find has a builtin "-delete" action, so you could do just find . -name \*.pyc -delete
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.
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?
-delete is not part of the POSIX specification, and not guaranteed to exist in all implementations of find.
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.
I
I159

find . -name '*.pyc' -delete

Surely the simplest.


If your version of find supports -delete; it is not part of the POSIX standard.
This ignores .pyo files and __pycache__ directories. See my answer.
I used the code from the accepted answer and it worked, but these commands are shorter and simple
-name '*.py?' to include .pyo, .pyc,...
MAKE SURE -delete is the last thing in the command. I accidentally put -delete right after the find. It deleted everything!
W
Wilfred Hughes

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

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.
j
jb.

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

Usage is simple:

pyclean .

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.
@holms pyclean (and now py3clean) originate in a Debian package, and thus aren’t in RHEL.
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.
A
Asclepius

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

What's the difference in running rm **/*.pyc vs rm */*.pyc? (The latter seemed to work for me locally.)
@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+
@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).
h
haki

For windows users:

del /S *.pyc

Putting this in a batch script makes things super easy. Thanks.
And if you are on Powershell, this can be used with "cmd" -> Run command -> "exit".
m
miku

I used to use an alias for that:

$ which pycclean

pycclean is aliased to `find . -name "*.pyc" | xargs -I {} rm -v "{}"'

In current debian it is pyclean.
This doesn't deal with whitespace in filenames well. You should use find -print0 and xargs -0 instead.
Why would you want to have python code with spaces in the file/folder names? Is that syntactically legal?
@CoreDumpError, yes, in fact on Windows Python installs to a directory with spaces ("Program Files").
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.
R
Ron Romero
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.


M
Moxdata
$ find . -name '*.pyc' -delete

This is faster than

$ find . -name "*.pyc" -exec rm -rf {} \;

M
Mithril

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

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.
They do if you install the tooling. I'd recommend every windows CLI user do so to ease cross-compat: superuser.com/questions/168202/…
Y
Yeo

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.


C
Clint Miller

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

rm `find . -name *.pyc`

This has the slight drawback of failing if there are too many matches, as there will be too many arguments to pass to rm.
r
romuloigor

full recursive

ll **/**/*.pyc
rm **/**/*.pyc

Interesting, how does this compare to Andy and Bill's answers?
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.
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 enabled
K
Kevin Sabbe

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

m
mo-han

Now there is a package pyclean on PyPI, which is easy to use, and cross-platform. User just need a simple command line to clean all __pycache__ files in current dir:

pyclean .

C
Community

First run:

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

Then add:

export PYTHONDONTWRITEBYTECODE=1

To ~/.profile


C
Chris Lutz

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.


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)
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...
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).
P
PiyusG
find . -name "*.pyc"|xargs rm -rf

G
Girish Vas

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

g
gpap

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.


A
AB Abhi

To delete all the python compiled files in current directory.

find . -name "__pycache__"|xargs rm -rf
find . -name "*.pyc"|xargs rm -rf

M
Milovan Tomašević

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

C
Chance

py3clean works for me!

cd /usr/local/lib/python3.9
sudo py3clean -v .