如何从项目中删除所有的 .pyc 文件?

744

我已经在一个相当大的项目中重命名了一些文件,并希望删除它们留下的 .pyc 文件。我尝试了这个 bash 脚本:

 rm -r *.pyc

但是它没有像我想的那样递归文件夹。我哪里出错了?


13
这个不行是因为在UNIX中,通配符是由shell扩展的而不是运行程序。如果当前目录下有a.pyc和b.pyc以及目录foo和bar,那么"rm"命令将被调用并带上参数[-r, a.pyc, b.pyc]。 - ephemient
2
如果你担心将你的代码推送给其他人,你可以将它添加到.gitignore文件中: **/*.pyc 这样你就不用再担心它了。 - bubakazouba
25个回答

1292
find . -name "*.pyc" -exec rm -f {} \;

439
Find命令自带了“-delete”选项,因此你可以只输入 find . -name \*.pyc -delete 就能删除所有匹配的".pyc"文件。 - Christoffer
59
最重要的是,如果这是开发机器,你可以设置PYTHONDONTWRITEBYTECODE=True,这样你就再也不需要重复这个步骤了。参见:这个答案 - mlissner
5
你没有引用{}。如果不小心拆分并删除一个叫做路径片段的中间路径,而这个路径片段恰好与你发现的路径中的某个片段相同,会发生什么? - Robottinosino
22
-delete 不是 POSIX 规范的一部分,也不保证会存在于所有 find 命令的实现中。 - chepner
8
如果你感到害怕——这可能是好事——可以先试用 -exec echo {},或者如果你非常害怕,可以使用 rm -i {},它会每次询问你是否要删除,或者使用 rm -v {},这样你就可以看到你删除的内容。 - Yano
显示剩余5条评论

1070

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

这无疑是最简单的。


23
如果您的 find 版本支持 -delete,那么它并不是 POSIX 标准的一部分。 - chepner
4
这忽略了.pyo文件和__pycache__目录。请看我的回答。 - Wilfred Hughes
@MattCaldwell rm 不够吗(去掉 -f)? - duozmo
3
-name '*.py?' 修改为包括 .pyo, .pyc,... 的表达式。 - cdosborn
2
请确保-delete是命令中的最后一项。我不小心把-delete放在了find之后,结果删除了所有内容! - thinkanotherone
显示剩余3条评论

96

在你的~/.bashrc文件中添加:

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

这将删除所有的 .pyc 和 .pyo 文件,以及 __pycache__ 目录。它也非常快速。

使用方法非常简单:

$ cd /path/to/directory
$ pyclean

find . -type d -name "__pycache__" -delete 经常会因为似乎在文件夹被删除之前,其内容将被添加到队列中而导致缺少路径的警告。 2>/dev/null 可以解决这个问题。 - Mad Physicist

88
在当前版本的Debian中,您可以使用“python-minimal”软件包中的“pyclean”脚本。
使用方法很简单:
pyclean .

36
值得注意的是,pyclean似乎只会删除存在相应.py文件的.pyc文件(至少在我的系统上——ubuntu 12.10)。这意味着在源文件已被删除且想要清理剩余的.pyc文件时,它并不太有帮助。 - tigerFinch
1
@holms pyclean (以及现在的py3clean)源于Debian包,因此不适用于RHEL。 - duozmo
1
pyclean 命令现在作为 Python 包可用,可以从 PyPI 安装(https://pypi.org/project/pyclean/),它可以跨平台使用(包括 RHEL、macOS 和 Windows)。它会删除任何 .pyc 文件,没有特殊的优先级。 - Peterino

53

如果您使用的是bash >=4.0(或zsh)

rm **/*.pyc

注意,*/*.pyc 选择所有一级子目录中的 .pyc 文件,而 **/*.pyc 会递归扫描整个目录树。例如,foo/bar/qux.pyc 将被 rm **/*.pyc 删除,但不会被 */*.pyc 删除。

必须启用 globstar shell 选项才能使用此功能。要启用 globstar

shopt -s globstar

并检查它的状态:

shopt globstar

1
运行 rm **/*.pycrm */*.pyc 有什么区别?(后者在本地似乎可以工作。) - Taylor D. Edmiston
1
@TaylorEdmiston rm */*.pyc 将删除深度为1的所有子目录中的所有 .pyc 文件。rm **/*.pyc 将删除深度为0或更深的所有子目录中的所有 .pyc 文件。 - Adam Stewart
1
@AdamStewart 感谢您的添加。对于在此主题上有疑问的其他人,我遇到的问题是苹果自带的 OS X bash 不包含 globstar(因此,在运行时 ** 表示为 *,并且运行“shopt globstar”会抛出错误)。 - Taylor D. Edmiston

35

对于Windows用户:

del /S *.pyc

将此放入批处理脚本中可使事情变得非常容易。谢谢。 - Nick Gotch
如果你在使用Powershell,可以用以下命令:"cmd" -> 运行命令 -> "exit"。 - Niko Pasanen

30

我曾经用一个别名来代替它:

$ which pycclean

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

12
在当前的Debian系统中,使用的是pyclean命令。 - jb.
7
这段代码对文件名中的空格处理得不太好。应该使用 find -print0xargs -0 代替。 - r3m0t
2
你为什么想要在文件/文件夹名称中使用空格的Python代码?那在语法上合法吗? - coredumperror
@CoreDumpError,实际上在Windows上,Python安装到一个带有空格的目录(“Program Files”)中。 - Paul Draper
Python解释器可能默认安装在那里,但那绝不是放置代码的好地方。此外,您肯定不希望“程序文件”文件夹成为您的包结构的一部分,这就是我对语法持谨慎态度的原因。 - coredumperror

18
find . -name '*.pyc' -print0 | xargs -0 rm

该find命令递归查找*.pyc文件。xargs接收这个名称列表并将其发送到rm。-print0和-0告诉这两个命令使用空字符分隔文件名。这使得它可以正确处理包含空格甚至包含换行符的文件名。

使用-exec的解决方案也可行,但对于每个文件都会启动一个新的rm副本。在系统缓慢或有大量文件的情况下,这将耗费太长时间。

您还可以添加几个参数:

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

iname选项添加了大小写不敏感,就像*.PYC文件一样。 no-run-if-empty避免了在没有这些文件时从rm命令中获得错误。


16
$ find . -name '*.pyc' -delete

这比原来更快。

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

15

此外,人们通常想要递归地从当前目录中删除所有*.pyc*.pyo文件和__pycache__目录。

命令:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf

这是一个很好的答案,但是一个简单的Python解决方案将是跨平台的,因此更可取。尽管我个人不关心Windows,但大约一半的Python用户使用Windows -- 而findgrep和其他类似命令在那里无法工作。 - Peterino
如果您安装了工具,它们就可以使用。我建议每个Windows CLI用户这样做以便于跨平台兼容性:https://superuser.com/questions/168202/difference-between-unxutils-and-gnuwin32 - DylanYoung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接