我在一个相当大的项目中重命名了一些文件,并希望删除它们留下的.pyc文件。我试过bash脚本:
但这不会像我想象的那样在文件夹中重现。我做错什么了?
- 它不起作用,因为在UNIX中,全局是由shell扩展的,而不是由正在运行的程序扩展的。如果当前目录中有a.pyc和b.pyc,以及foo和b a r目录,那么将使用参数[-r,a.pyc,b.pyc]调用rm。
- 如果你担心把你的代码推给别人,你可以把它添加到.gitignore **/*.pyc中,这样你就不用再担心了。
1
| find . -name"*.pyc" -exec rm -f {} \; |
- 我测试了这两个。目录可能太小而不重要,但它的速度比我的快,这是我所期望的,因为我必须组装列表,然后遍历它,而您的目录则会删除找到的每个项目。
- find有一个内置的"-delete"操作,所以您可以只执行find . -name \*.pyc -delete。
- 最重要的是,如果这是一台dev机器,您可以将pythondontwritebytecode设置为true,并且您将不再需要这样做。看:这个答案。
- 你方没有报价。如果不小心单词被拆分并删除了一个中间路径,而这个中间路径恰好被称为您找到的路径的一个片段,会发生什么?
- 在我的.bashrc中:alias rmPyCrap="find . -name \*.pyc -delete && find . -type d -name __pycache__ -delete"。
- -delete不是posix规范的一部分,并且不能保证在find的所有实现中都存在。
- 如果你害怕-这可能很好-第一次通过-exec echo,或者-如果你非常害怕-使用每次询问你的rm-i或rm-v,这样你就能看到你删除了什么。
- 确认这一点对我在Mac OSX Mavericks上很有用。
- 在哪里可以设置pythondontwritebytecode?有什么我可以编辑的文件吗?
find . -name '*.pyc' -delete
当然是最简单的。
- + 1。这个命令比目前被蜥蜴比尔接受的命令要安全得多。任何一个包含rm -rf的命令都有点可怕。:)
- 另外,考虑到这里不需要"-r"。rm-f"就足够了。
- 如果您的find版本支持-delete;它不是posix标准的一部分。
- 这会忽略.pyo文件和__pycache__目录。看看我的答案。
- 我使用了被接受的答案中的代码,它起作用了,但是这些命令又短又简单
- @Mattcaldwell是不是rm不够(drop -f)?
- @鲁德茨沃林斯基,当你认为你心里知道它的时候,它不会感到安全,不要,省略了-name,删除了你的整个env!
- -name '*.py?'包括.pyo, .pyc,...。
- 确保-delete是命令中的最后一项。我不小心发现后就把-删除了。它删除了所有内容!
在当前版本的debian中,您有pyclean脚本,它位于python-minimal包中。
用法很简单:
- 值得注意的是,py clean似乎只删除.pyc文件,其中有相应的.py文件(至少在我的系统-Ubuntu 12.10上),这意味着在源文件已被删除并且您希望清除剩余的.pyc文件的情况下,它不是很有用。
- 对瑞尔不起作用,没有这样的命令。
- @霍尔姆斯·埃多克斯(Holms EDOCX1)(10)(现在的埃多克斯(EDOCX1)(11))起源于一个Debian包,因此不在RHEL中。
添加到您的~/.bashrc中:
1 2 3 4
| pyclean () {
find . -type f -name"*.py[co]" -delete
find . -type d -name"__pycache__" -delete
} |
这将删除所有.pyc和.pyo文件以及__pycache__目录。速度也很快。
用法很简单:
1 2
| $ cd /path/to/directory
$ pyclean |
- find . -type d -name"__pycache__" -delete通常会发出关于丢失路径的警告,因为很明显,在删除文件夹之前,内容将被添加到队列中。2>/dev/null应该解决这个问题。
如果使用bash>=4.0(或zsh)
注意,*/*.pyc选择直接一级子目录中的所有.pyc文件,而**/*.pyc递归扫描整个目录树。例如,foo/bar/qux.pyc将由rm **/*.pyc删除,而不是由*/*.pyc删除。
必须启用globstar外壳选项。启用globstar:
并检查其状态:
- 运行rm **/*.pyc和rm */*.pyc有什么区别?(后者似乎在本地为我工作。)
- @tayloledmiston rm */*.pyc将删除深度1的所有子目录中的所有.pyc文件。rm **/*.pyc将删除深度为0的所有子目录中的所有.pyc文件。+
- @Adamstewart感谢您添加此功能。对于其他在这方面遇到困难的人来说,我遇到的问题是苹果的OSX附带的bash不包括globstar(因此,当运行时,**充当*,而运行shopt globstar会抛出错误)。
我以前用化名:
1 2 3
| $ which pycclean
pycclean is aliased to `find . -name"*.pyc" | xargs -I {} rm -v"{}"' |
- 在当前的debian中,它是pyclean。
- 这并不能很好地处理文件名中的空白。您应该使用find -print0和xargs -0。
- 为什么要让文件/文件夹名中包含空格的python代码?这在语法上合法吗?
- @coredumerror,是的,实际上,在Windowspython上,安装到一个带有空格的目录("程序文件")。
- 默认情况下,python解释器可能会安装在那里,但它不是放置代码的好地方。另外,您肯定不希望程序文件文件夹成为包结构的一部分,这就是为什么我对语法很谨慎的原因。
1
| find . -name '*.pyc' -print0 | xargs -0 rm |
查找以递归方式查找*.pyc文件。xargs接受该名称列表并将其发送给rm。-print0和-0告诉这两个命令用空字符分隔文件名。这使得它能够正确地处理包含空格的文件名,甚至包含新行的文件名。
带有-exec的解决方案可以工作,但它会为每个文件提供一个新的RM副本。在一个缓慢的系统或有大量文件,这将花费太长时间。
您还可以添加几个参数:
1
| find . -iname '*.pyc' -print0 | xargs -0 --no-run-if-empty rm |
iname添加了不区分大小写,如*.pyc。如果没有这样的文件,那么no-run if-empty可以防止您从RM中得到错误。
对于Windows用户:
- 把它放到一个批处理脚本中可以让事情变得非常简单。谢谢。
1
| $ find . -name '*.pyc' -delete |
这比
1
| $ find . -name"*.pyc" -exec rm -rf {} \; |
此外,人们通常希望递归地删除当前目录中的所有*.pyc、*.pyo文件和__pycache__目录。
命令:
1
| find . | grep -E"(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf |
- 这是一个很好的答案,但是一个普通的Python解决方案是跨平台的,因此更可取。而就我个人而言,我不在乎Windows,可能有一半的python用户生活在Windows上,而find、grep和朋友不在那里工作。
Django延长线
Note: This answer is very specific to Django project that have already been using Django Extension.
1
| python manage.py clean_pyc |
可以在源代码中查看实现。
只需将另一个变体加入到组合中,您还可以使用这样的反引号:
- 这有一个小小的缺点,即如果匹配太多则失败,因为传递给rm的参数太多。
全递归
1 2
| ll **/**/*.pyc
rm **/**/*.pyc |
- 有趣的是,这和安迪和比尔的答案相比如何?
- 一组**是多余的,正如d0k的答案一样,您必须在bash 4+中启用globstar才能按预期工作。也就是说,shopt -s globstar或在某个源代码bash中使用它。文件夹。
- 另外,ll通常被称为ls -l之类的东西,但实际上不是命令或可移植的。因此,要递归地列出.中的所有.pyc文件,您应该在启用了globstar的情况下执行类似于echo **/*.pyc的操作。
- rm **/**/*.pyc为我的案子工作
第一次运行:
1
| find . -type f -name"*.py[c|o]" -exec rm -f {} + |
然后添加:
1
| export PYTHONDONTWRITEBYTECODE=1 |
对轮廓
1
| find . -name"*.pyc"|xargs rm -rf |
如果您不再需要.pyc,您可以在终端中使用此单行:
1
| export PYTHONDONTWRITEBYTECODE=1 |
如果你改变主意:
1
| unset PYTHONDONTWRITEBYTECODE |
rm -r递归到目录中,但只返回给rm的目录。它还将删除这些目录。一种解决方案是:
1 2 3 4
| for i in $( find . -name *.pyc )
do
rm $i
done |
find将在当前目录中递归查找所有*.pyc文件,for循环将遍历找到的文件列表,删除每个文件。
- 尽管我必须将它放在.sh文件中并运行它(这对我来说很好,我将多次使用此命令)
- 我相信把它放在一行上,用";"隔开,应该让你在壳上运行它。但是当我在bash中键入它时,bash会在最后等待"完成"来执行任何操作…
- 这是一个非常糟糕的反模式(也是一个非常常见的模式,我希望它可以消失):它与包含空格或glob字符的文件名中断。它的-exec谓词:find . -name '*.pyc' -exec rm {} +(更好、更短、更安全、更健壮、更高效)错过了find的要点。
你可以运行find . -name"*.pyc" -type f -delete。
但要小心使用。运行第一个find . -name"*.pyc" -type f查看您要删除的文件。
此外,请确保-delete是命令中的最后一个参数。如果将它放在-name*.pyc参数之前,它将删除所有内容。