【问题标题】:How do I remove all .pyc files from a project?如何从项目中删除所有 .pyc 文件?
【发布时间】:2010-10-21 14:15:55
【问题描述】:

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

 rm -r *.pyc

但这并没有像我想象的那样通过文件夹递归。我做错了什么?

【问题讨论】:

  • 它不起作用,因为在 UNIX 中,glob 由 shell 扩展,而不是由正在运行的程序扩展。如果当前目录中有 a.pyc 和 b.pyc 以及目录 foo 和 bar,则将使用参数 [-r, a.pyc, b.pyc] 调用 rm
  • 如果您担心将代码推送给其他人,您可以将其添加到 .gitignore **/*.pyc 中,您就不必再担心了

标签: bash


【解决方案1】:

现在PyPI上有一个包pyclean,使用方便,跨平台。用户只需要一个简单的命令行来清理当前目录中的所有__pycache__ 文件:

pyclean .

【讨论】:

    【解决方案2】:

    删除当前目录下的所有python编译文件。

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

    【讨论】:

      【解决方案3】:

      如果要递归删除当前目录中的所有*.pyc 文件和__pycache__ 目录:

      • 用python:
      import os
      
      os.popen('find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf')
      
      • 或使用终端或 cmd 手动:
      find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
      

      【讨论】:

        【解决方案4】:

        如果要从项目文件夹中删除所有 .pyc 文件。

        首先,你有

        cd <path/to/the/folder>
        

        然后找到所有的.pyc文件并删除。

        find . -name \*.pyc -delete
        

        【讨论】:

          【解决方案5】:

          此外,人们通常希望在当前目录中递归删除所有*.pyc*.pyo 文件和__pycache__ 目录。

          命令:

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

          【讨论】:

          • 这是一个很好的答案,但一个普通的 Python 解决方案将是跨平台的,因此更可取。虽然就我个人而言,我并不关心 Windows,但可能有一半的 Python 人口生活在 Windows 上——findgrep 和朋友们并不在那里工作。
          • 如果您安装了工具,它们就会这样做。我建议每个 Windows CLI 用户都这样做以简化交叉兼容:superuser.com/questions/168202/…
          【解决方案6】:

          你可以运行find . -name "*.pyc" -type f -delete

          但请谨慎使用。首先运行 find . -name "*.pyc" -type f 以查看您将删除哪些文件。

          此外,确保 -delete 是命令中的最后一个参数。如果将它放在 -name *.pyc 参数之前,它将删除所有内容。

          【讨论】:

            【解决方案7】:
            find . -name "*.pyc" -exec rm -f {} \;
            

            【讨论】:

            • Find 有一个内置的“-delete”动作,所以你可以只做find . -name \*.pyc -delete
            • 最重要的是,如果这是一台开发机器,您可以设置 PYTHONDONTWRITEBYTECODE=True,您再也不需要这样做了。请参阅:this answer
            • 你没有引用{}。如果不小心分词并删除了一个中间路径,该路径恰好被称为您找到的路径的片段,会发生什么情况?
            • -delete 不是 POSIX 规范的一部分,并且不保证存在于 find 的所有实现中。
            • 如果你害怕 - 这可能很好 - 使用 -exec echo {} 进行第一遍,或者 - 如果你非常害怕 - 使用 rm -i {}每次都会询问您或 rm - v {} 以便您查看删除的内容。
            【解决方案8】:

            如果您不再需要 .pyc,您可以在终端中使用这一行:

            export PYTHONDONTWRITEBYTECODE=1
            

            如果你改变主意:

            unset PYTHONDONTWRITEBYTECODE
            

            【讨论】:

              【解决方案9】:

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

              rm **/*.pyc
              

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

              必须启用 globstar shell 选项。启用globstar

              shopt -s globstar
              

              并检查其状态:

              shopt globstar
              

              【讨论】:

              • 运行rm **/*.pycrm */*.pyc 有什么区别? (后者似乎在本地对我有用。)
              • @TaylorEdmiston rm */*.pyc 将删除深度为 1 的所有子目录中的所有 .pyc 文件。rm **/*.pyc 将删除深度为 0+ 的所有子目录中的所有 .pyc 文件
              • @AdamStewart 感谢您添加此内容。对于其他在这个线程上绊倒的人,我遇到的问题是 OS X 附带的 Apple bash 不包括 globstar(所以** 在运行时充当* 而运行shopt globstar 会引发错误)。跨度>
              【解决方案10】:

              find . -name '*.pyc' -delete

              当然是最简单的。

              【讨论】:

              • 如果你的find版本支持-delete;它不是 POSIX 标准的一部分。
              • 这会忽略 .pyo 文件和 __pycache__ 目录。看我的回答。
              • 我使用了接受的答案中的代码并且它有效,但是这些命令更短更简单
              • -name '*.py?' 包括.pyo, .pyc,...
              • 确保 -delete 是命令中的最后一件事。我不小心把 -delete 放在了找到之后。它删除了所有内容!
              【解决方案11】:

              Django 扩展

              注意:此答案非常针对已经使用Django ExtensionDjango project

              python manage.py clean_pyc
              

              实现可以在its source code查看。

              【讨论】:

                【解决方案12】:

                Windows 用户:

                del /S *.pyc
                

                【讨论】:

                • 把它放在一个批处理脚本中让事情变得超级简单。谢谢。
                • 如果你在 Powershell 上,这可以与 "cmd" -> Run command -> "exit" 一起使用。
                【解决方案13】:
                find . -name "*.pyc"|xargs rm -rf
                

                【讨论】:

                  【解决方案14】:

                  第一次运行:

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

                  然后添加:

                  export PYTHONDONTWRITEBYTECODE=1
                  

                  到 ~/.profile

                  【讨论】:

                    【解决方案15】:
                    $ find . -name '*.pyc' -delete
                    

                    这比

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

                    【讨论】:

                      【解决方案16】:

                      添加到您的~/.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&gt;/dev/null 应该可以解决这个问题。
                      【解决方案17】:
                      find . -name '*.pyc' -print0 | xargs -0 rm
                      

                      查找递归地查找 *.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 收到错误。

                      【讨论】:

                        【解决方案18】:

                        我曾经为此使用别名:

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

                        【讨论】:

                        • 在当前的 debian 中是 pyclean。
                        • 这不能很好地处理文件名中的空格。您应该改用find -print0xargs -0
                        • 为什么要在文件/文件夹名称中使用带有空格的 python 代码?这在语法上合法吗?
                        • @CoreDumpError,是的,实际上在 Windows 上,Python 安装到带有空格的目录(“程序文件”)。
                        • python 解释器可能默认安装在那里,但它不是放置代码的好地方。另外,您当然不希望 Program Files 文件夹成为您的包结构的一部分,这就是我对语法持谨慎态度的原因。
                        【解决方案19】:

                        在当前版本的 debian 中,pyclean 脚本位于 python-minimal 包中。

                        用法很简单:

                        pyclean .
                        

                        【讨论】:

                        • 值得注意的是,pyclean 似乎只删除有相应 .py 文件的 .pyc 文件(至少在我的系统上 - ubuntu 12.10)。这意味着它在以下情况下不是很有帮助源文件已被删除,您要清理剩余的 .pyc 文件。
                        • @holms pyclean(现在是 py3clean)源自 Debian 软件包,因此不在 RHEL 中。
                        • pyclean 命令现在以 Python 包installable from PyPI 的形式提供,它可以跨平台(包括 RHEL、macOS 和 Windows)工作。从今天开始,它会删除任何没有特殊偏好的 .pyc 文件。
                        【解决方案20】:

                        全递归

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

                        【讨论】:

                        • 有趣,这与安迪和比尔的答案相比如何?
                        • 一组** 是多余的,就像d0k 的答案一样,您必须在 bash 4+ 中启用 globstar 才能按预期工作。即做 shopt -s globstar 或在您的一个来源 bash 中使用它。文件。
                        • 另外,ll 通常别名为ls -l,但它并不是真正的命令或可移植的。因此,要递归列出. 中的所有.pyc 文件,您应该改为在启用globstar 的情况下执行echo **/*.pyc 之类的操作
                        【解决方案21】:

                        只是为了添加另一个变体,您还可以使用这样的反引号:

                        rm `find . -name *.pyc`
                        

                        【讨论】:

                        • 如果匹配太多会失败,因为传递给rm的参数太多。
                        【解决方案22】:

                        rm -r 递归到目录中,但仅限于您提供给rm 的目录。它还将删除这些目录。一种解决方案是:

                        for i in $( find . -name *.pyc )
                        do
                          rm $i
                        done
                        

                        find 将在当前目录中递归查找所有 *.pyc 文件,for 循环将遍历找到的文件列表,删除每个文件。

                        【讨论】:

                        • 虽然我必须把它放在一个 .sh 文件中并运行它(这对我来说很好,我会多次使用这个命令)
                        • 我相信将它全部放在用';'s 分隔的一行应该可以让你在shell 上运行它。但是当我在 bash 中输入时,bash 会等待最后的“完成”来执行任何操作......
                        • 这是一个糟糕的反模式(也是一个非常常见的模式,我希望它可以消失):它会因包含空格或全局字符的文件名而中断。它错过了find 的意义,因为它的-exec 谓词:find . -name '*.pyc' -exec rm {} +(更好、更短、更安全、更健壮、更高效)。
                        猜你喜欢
                        • 1970-01-01
                        • 2015-05-13
                        • 2011-07-19
                        • 2014-06-09
                        • 1970-01-01
                        • 2014-09-15
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多