【问题标题】:Remove empty folders (Python)删除空文件夹(Python)
【发布时间】:2017-11-03 10:30:06
【问题描述】:

这是文件夹树:

FOLDER\\
       \\1\\file
       \\2\\file
       \\3\\
       \\4\\file

脚本应该扫描(循环)文件夹中的每个文件夹,并检查子文件夹是否为空。如果是,则必须将其删除。

到目前为止,我的代码是这样的:

folders = ([x[0] for x in os.walk(os.path.expanduser('~\\Desktop\\FOLDER\\DIGITS\\'))])
folders2= (folders[1:])

此扫描文件夹并使用folders2 从DIGITS 中的第一个文件夹开始。 在DIGITS 中有编号的目录:1、2、3、4 等

现在呢?尝试使用os.rmdir,但它给了我一个错误,关于字符串。其实folders2是一个列表,不是字符串,只是说...

【问题讨论】:

    标签: python directory


    【解决方案1】:

    不知道你得到什么样的错误,这对我来说非常有用:

    import os
    
    root = 'FOLDER'
    folders = list(os.walk(root))[1:]
    
    for folder in folders:
        # folder example: ('FOLDER/3', [], ['file'])
        if not folder[2]:
            os.rmdir(folder[0])
    

    【讨论】:

    • 我的意思是在一个 for 循环中。也许我错了......无论如何,答案完美地完成了这项工作。
    • 是的,此解决方案在以下几种情况下不起作用:1)递归(如果文件夹深度超过 1 级)2)如果文件夹有内部文件夹但其中没有文件
    • 对于这个特定案例,我想要什么。谢谢。
    • 虽然这回答了问题,但有很多问题! 1、根目录为空怎么办? 2. 如果一个目录只有所有子目录会怎样? 3. 您将生成器转换为列表只是为了跳过您不需要的第一个元素。
    【解决方案2】:
    #LOOP THROUGH ALL SUBFOLDERS FIRST
    
    import os
    root = os.getcwd() #CHANGE THIS TO PATH IF REQUIRED
    folders = sorted(list(os.walk(root))[1:],reverse=True)
    for folder in folders:
        try:
            os.rmdir(folder[0])
        except OSError as error: 
            print("Directory '{}' can not be removed".format(folder[0])) 
    

    这应该首先遍历所有子文件夹,如果是空文件夹,则删除。不删除父文件夹的非空文件夹。

    我知道这是一篇旧帖子,但我自己也老了!!!

    【讨论】:

      【解决方案3】:

      几乎是 Iván B. 所说的,但做了一个对我有用的小改动

      import os, shutil
      path_abs=('YourPath')
      walk = list(os.walk(path_abs))
      for path, _, _ in walk[::-1]:
          if len(os.listdir(path)) == 0:
              os.rmdir(path)
      

      【讨论】:

        【解决方案4】:

        您可以使用以下 sn-p 删除所有空文件夹和子文件夹。

        import os
        
        
        def remove_empty_folders(path_abs):
            walk = list(os.walk(path_abs))
            for path, _, _ in walk[::-1]:
                if len(os.listdir(path)) == 0:
                    os.remove(path)
        
        if __name__ == '__main__':
            remove_empty_folders("your-path")
        

        【讨论】:

        【解决方案5】:

        有几件事可以扩展其他答案:

        如果您使用os.walk(topdown=False),它会以相反的顺序进行,因此您会在父目录之前遇到子目录。然后,如果您跟踪删除了哪些目录,则可以递归删除父目录。

        import os
        
        
        def delete_empty_folders(root):
        
            deleted = set()
            
            for current_dir, subdirs, files in os.walk(root, topdown=False):
        
                still_has_subdirs = any(
                    _ for subdir in subdirs
                    if os.path.join(current_dir, subdir) not in deleted
                )
            
                if not any(files) and not still_has_subdirs:
                    os.rmdir(current_dir)
                    deleted.add(current_dir)
        
            return deleted
        
        

        【讨论】:

          【解决方案6】:
          import os
          
          directory = r'path-to-directory'
          
          for entry in os.scandir(directory):
              if os.path.isdir(entry.path) and not os.listdir(entry.path) :
                  os.rmdir(entry.path)
          

          在这里你可以找到对scandir的很好的介绍/解释

          【讨论】:

          • 您是否介意编辑您的答案以帮助读者理解为什么这种方法可能比已接受的答案(或者,实际上,前三个答案中的任何一个)更可取?
          • 如果你打算使用 scandir,我认为如果你使用 os.path.isdir() 而不是 entry.is_dir() 你不会得到太多的好处 - 重点是它由于不需要额外的 stat() 调用而更快,并且 os.path.isdir() 正在执行该 stat() 调用,不是吗?
          【解决方案7】:

          对于空文件夹删除,您可以使用这个 sn-p。

          import os
          
          
          def drop_empty_folders(directory):
              """Verify that every empty folder removed in local storage."""
          
              for dirpath, dirnames, filenames in os.walk(directory, topdown=False):
                  if not dirnames and not filenames:
                      os.rmdir(dirpath)
          

          【讨论】:

          • 这不适用于具有空子文件夹的文件夹。子文件夹被删除,但父文件夹 - 即使在删除子文件夹后被评估 - 仍然会在 dirnames 中看到子文件夹。虽然 topdown=False 很好。
          【解决方案8】:

          此答案修复了当前接受的答案中的问题。主要问题是删除目录的条件必须是not filenames and not dirnames。

          import os
          
          def remove_empty_directories(root):
              for dirpath, dirnames, filenames in os.walk(root):
                  if not filenames and not dirnames:
                      os.rmdir(dirpath)
          

          【讨论】:

            【解决方案9】:

            仅当文件夹为空时删除:

            import os
            import shutil
            
            if len(os.listdir(folder_path)) == 0: # Check if the folder is empty
                shutil.rmtree(folder_path) # If so, delete it
            

            【讨论】:

            • 您需要将import shutil 添加到答案中的导入中
            • 你可以用它来打自己的腿,因为 os.listdir 并不总是正确地返回网络共享上的文件(例如,“挂起”nfs 正在重新安装过程中将在卸载时刻),shutil.rmtree 在这些情况下可能会让您没有文件...
            • 嘿@Anubioz,我没有遇到你描述的这种情况,但我学到了一些东西,谢谢:)
            【解决方案10】:

            我建议你调用这个函数,它设计了一个可选参数。 如果将in_place 设置为False,它不会删除文件夹,只会将它们作为列表返回。同时,如果您将其设置为True,该函数将删除空文件夹,而不管子目录树的深度如何。

            P.S.如果您需要深度限制,您可以通过根路径之后的元素进行分析。

            import os
            import shutil
            
            def purge_dir(dir, in_place=False):
            
                deleted = []
                dir_tree = list(os.walk(dir, topdown=False))
            
                for tree_element in dir_tree:
                    sub_dir = tree_element[0]
                    is_empty = not len(os.listdir(sub_dir))
                    if is_empty:
                        deleted.append(sub_dir)
            
                if in_place:
                    list(map(os.rmdir, deleted))
            
                return deleted
            

            我建议您将in_place 设置为False 返回空文件夹并随意使用它,因为它更安全,尤其是对于安全关键型应用程序。

            【讨论】:

              猜你喜欢
              • 2020-07-23
              • 1970-01-01
              • 1970-01-01
              • 2010-09-23
              • 2015-12-25
              • 1970-01-01
              • 2017-02-19
              • 1970-01-01
              • 2019-08-16
              相关资源
              最近更新 更多