有些時候我們會遇到這樣的需求,需要刪除某個目錄,但這個目錄下有個別的文件或文件夾需要保留
下面這個腳本就是用來處理這類問題
# #針對大目錄下保留部分子目錄的程序化處理方案 # 1.從大目錄列出下一級目錄,匹配是否是需要保留的子目錄的前綴,如果不是,保存到待刪除dir_list # 2.如果是父目錄,則判斷是否等於待排除目錄,如果等於,則不做處理,不等於則繼續下沉 # 3.遞歸獲取下一級目錄,先判斷獲取的目錄list是否為空,如果為空,則不做處理,否則將list中的key存入隊列 # 4.處理到隊列為空 import os from queue import Queue q = Queue() def get_complex_list(key, exclude_list): target_list = [] # 隊列初始化 q.put(key) while not q.empty(): # 判斷當前目錄是否是將要排除的目錄的父目錄 get_key = q.get() is_parent = is_parent_path_for_list(get_key, exclude_list) # 如果不是放入目標list, 是則獲取下層目錄放入隊列 if not is_parent: target_list.append(get_key) # 如果是進行二次判斷,是否等於將要排除的目錄 else: # 如果目錄不等於將要排除的目錄,則進行下沉 if not is_equal_for_list(get_key, exclude_list): tmp_list = get_sub_list(get_key) # 如果tmp_list不為空則存入隊列進行下一輪循環 if tmp_list: for tmp in tmp_list: q.put(tmp) return target_list def is_parent_path_for_list(parent_path, path_list): is_parent_list = [is_parent_path(parent_path, path) for path in path_list] return any(is_parent_list) def is_equal_for_list(parent_path, path_list): is_equal_list = [parent_path == path for path in path_list] return any(is_equal_list) def is_parent_path(parent_path, path): return path.startswith(parent_path) def get_sub_list(key): key = key if key.endswith('/') else key + '/' s3_ls_cmd = "aws s3 ls {key}".format(key=key) p = os.popen(s3_ls_cmd) ret = p.read() p.close() catalog_list = [item.lstrip() for item in ret.split('\n')] s3_key_list = ["{key}{new_key}".format(key=key, new_key=catalog[4:]) for catalog in catalog_list if catalog != '' and catalog.endswith('/')] print(s3_key_list) return s3_key_list if __name__ == '__main__': parent_path = 's3://.../' path_list = ['s3://.../.../'] result = get_complex_list(parent_path, path_list) print(result)