实际应用中的Python-批量删除文件夹

2,166 阅读3分钟

最近公司给换电脑了,之前老电脑中保存了很多的项目,想把这些项目拷贝到新电脑中,直接复制这些项目的话太大了,因为几乎每个项目中都有一些与项目无关的内容,比如build文件夹、.idea文件夹、.gradle文件夹等,如果一个一个删除太耗时了,此时可以用python删除。逻辑就是循环遍历文件夹,如果是.gradle、.idea、build文件夹就删除,如果是其他的,比如.git、src等可以跳过,防止递归深度过深导致 RecursionError: maximum recursion depth exceeded in comparison异常(详见:blog.csdn.net/cliviabao/a…

代码更新

import getopt
import os
import os.path as path_utils
import sys

DELETE_LIST = ['build', '.gradle', '.idea']
SKIP_LIST = ['.git', 'gradle', 'src', 'libs']
DANGEROUS_DELETE = True

ARG_D = 'd'
ARG_DIR = 'dir'


def iter_projects(path):
    """
    遍历项目列表
    :return: None
    """

    # 获取当前路径文件夹列表
    projects = os.listdir(path)

    # 空文件夹直接返回
    if not projects:
        return

    for project in projects:
        project_path = path_utils.join(path, project)
        print("begin clean project: " + project)
        clean_project(project_path)
        print("end clean project: " + project + "\n")


def clean_project(path):
    """
    清理当前项目
    :param path: 项目路径
    :return: None
    """
    if path_utils.isdir(path):  # 项目路径有效
        # 获取项目子文件列表
        dirs = os.listdir(path)

        # 遍历子文件夹
        for file in dirs:
            if file in SKIP_LIST:  # 在跳过列表中,直接跳过
                print("skip: " + file)
                continue
            if file in DELETE_LIST:  # 在删除列表中,执行删除
                print("delete: " + file)
                garbage_path = path_utils.join(path, file)
                del_file_or_path(garbage_path)


def del_file_or_path(path):
    """
    递归删除目录及其文件
    :param path: 待删除的路径
    :return: None
    """
    dirs = os.listdir(path)  # 获取列表

    # 空文件夹直接删除
    if not dirs:
        print("remove empty dir: " + path)
        if DANGEROUS_DELETE:
            os.removedirs(path)
        return

    # 遍历当前文件夹
    for i in dirs:
        file = path_utils.join(path, i)  # 获取文件绝对路径

        if path_utils.isfile(file):  # 文件直接删除
            print("remove file: " + file)
            if DANGEROUS_DELETE:
                os.remove(file)
        else:  # 文件夹递归
            del_file_or_path(file)

    # 文件删除完成,开始删除文件夹
    print("remove deleted empty dir: " + path)
    if DANGEROUS_DELETE:
        if path_utils.exists(path):
            os.removedirs(path)


if __name__ == '__main__':
    projects_path = sys.path[0]  # 待分析的路径,默认为当前路径

    argv = sys.argv[1:]

    try:
        """
            options, args = getopt.getopt(args, shortopts, longopts=[])

            参数args:一般是sys.argv[1:]。过滤掉sys.argv[0],它是执行脚本的名字,不算做命令行参数。
            参数shortopts:短格式分析串。例如:"hp:i:",h后面没有冒号,表示后面不带参数;p和i后面带有冒号,表示后面带参数。
            参数longopts:长格式分析串列表。例如:["help", "ip=", "port="],help后面没有等号,表示后面不带参数;ip和port后面带冒号,表示后面带参数。

            返回值options是以元组为元素的列表,每个元组的形式为:(选项串, 附加参数),如:('-i', '192.168.0.1')
            返回值args是个列表,其中的元素是那些不含'-'或'--'的参数。
        """

        opts, args = getopt.getopt(argv, ARG_D + ":", [ARG_DIR + "="])
    except getopt.GetoptError:
        print("Error: 参数有误,请正确输入待分析的文件夹以及结果文件夹")
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-" + ARG_D, "--" + ARG_DIR):
            projects_path = arg

    print('current_path: ' + projects_path)
    iter_projects(projects_path)

旧代码如下:

# coding:utf-8
import os
import sys
import platform


class RemoveTagFile(object):
    path = None

    def removeFile(self, path, remove_list, jump_list):  # path后面要跟/
        self.path = path
        system_test = platform.system()
        if(system_test == 'Windows'):
            path_last = self.path[-1]
            if(path_last != '\\'):
                self.path = self.path+'\\'
        elif(system_test == 'Linux'):
            path_last = self.path[-1]
            if (path_last != '/'):
                self.path = self.path + '/'

        self.remove_file(self.path, self.eachFile(self.path))

    def remove_file(self, path, file_list):
        for filename in file_list:
            dirOrFile = path + filename
            if(os.path.exists(dirOrFile)):  # 判断文件是否存在
                if(filename in jump_list):  # 判断是否是需要跳过的文件或文件夹
                    print("jump: " + dirOrFile)
                    continue

                if(filename in remove_list):    # 如果在移除列表则移除
                    if(os.path.isdir(dirOrFile)):
                        print("delDir: " + dirOrFile)
                        self.del_file(dirOrFile)
                        self.del_dir(dirOrFile)
                    else:
                        if(os.path.exists(dirOrFile)):
                            print("delFile: " + dirOrFile)
                            os.remove(dirOrFile)
                else:   #没有在移除列表:如果是文件就跳过,是文件夹则进入
                    if(os.path.isdir(dirOrFile)):
                        self.remove_file(dirOrFile + "\\", self.eachFile(dirOrFile + "\\"))
            else:
                print(dirOrFile + ' is not exist!')

    def del_file(self, path):  # 递归删除目录及其子目录下的文件
        for i in os.listdir(path):
            path_file = os.path.join(path, i)  # 取文件绝对路径
            if os.path.isfile(path_file):  # 判断是否是文件
                os.remove(path_file)
            else:
                self.del_file(path_file)

    def del_dir(self, path):  # 删除文件夹
        listDirs = os.listdir(path)
        if not listDirs:    # 空文件夹直接删除
            os.removedirs(path)
            return
        for j in os.listdir(path):
            path_file = os.path.join(path, j)  # 取文件绝对路径
            if not os.listdir(path_file):  # 判断文件如果为空
                os.removedirs(path_file)  # 则删除该空文件夹,如果不为空删除会报异常
            else:
                self.del_dir(path_file)

    def eachFile(self, filepath):  # 获取目录下所有文件的名称
        pathDir = os.listdir(filepath)
        list = []
        for allDir in pathDir:
            child = os.path.join('%s%s' % (filepath, allDir))
            fileName = child.replace(filepath, '')
            list.append(fileName)
        return list


if __name__ == '__main__':
    rtf = RemoveTagFile()
    # 以下表示只删除D:\Test\目录下的a文件夹、a.txt文件、b.txt文件
    """
    规则:
    1、remove_list: 需要删除的文件夹
    2、jump_list:需要跳过的文件夹
    """

    path = 'F:\github\Android\AmazingAvatar'
    remove_list = ['build', '.gradle', '.idea', 'bb.txt']  # 要删除的文件名称
    jump_list = ['.git', 'gradle', 'src', 'libs']  # 要保留的文件名称
    rtf.removeFile(path, remove_list, jump_list)

参考文章:www.cnblogs.com/shuyichao/p…