假设我们有一个像这样的结构的目录,我将目录标记为(+),将文件标记为( - )
rootdir
+a
+a1
-f1
-f2
+a2
-f3
+b
+b1
+b2
-f4
-f5
-f6
+b3
-f7
-f8
和给定的文件列表,如
/a/a1/f1
/b/b1/b2/f5
/b/b3/f7
我很难找到删除root中的所有文件的方法,除了给定列表中的文件。所以在程序执行后,根目录应如下所示:
rootdir
+a
+a1
-f1
+b
+b1
+b2
-f5
+b3
-f7
这个例子只是为了更容易理解问题。实际上,给定列表包括大约4千个文件。根目录的大小约为15GB,内部有数十万个文件。
在文件夹内搜索,以及在给定列表中匹配的 REMOVE 文件很容易。我们只需要解决 REVERT 问题,解决在给定列表中匹配的 KEEP 文件。
更喜欢用Perl / Python编写的程序。
有人可以提出建议吗?
谢谢你,并致以最诚挚的问候。
亚历
答案 0 :(得分:2)
首先,将要保留的文件列表存储在关联容器中,如Python dict
或某种地图。
其次,只需在整个目录结构上迭代(在Python中,os.walk
),每次看到文件时,检查它是否在要保留的路径的关联容器中。如果没有,删除它(在Python中,os.unlink
)。
可替换地:
首先,在同一文件系统上创建一个临时目录。
其次,移动(os.renames
,根据需要生成新的子目录)所有“保留”文件到临时目录,具有相同的结构。
第三,用临时目录覆盖(os.removedirs
后跟os.rename
或仅shutil.move
)原始目录。
答案 1 :(得分:1)
这是您的问题的有效代码。
import os
def list_files(directory):
for root, dirs, files in os.walk(directory):
for name in files:
yield os.path.join(root, name)
files_to_delete = {'/home/vedang/Desktop/a.out', '/home/vedang/Desktop/ABC/temp.txt'} #Keep a set instead of list for faster lookups
for f in list_files('/home/vedang/Desktop'):
if f in files_to_delete:
os.unlink(f)
答案 2 :(得分:1)
这是一个函数,它接受一组您希望保留的文件以及您希望开始删除文件的根目录。 这是一个经典的递归深度优先搜索,它会在删除所有不需要的文件后删除空目录 导入操作系统
def delete_files(keep_list:set, curr_dir):
files = os.listdir(curr_dir)
for f in files:
path = f"{curr_dir}/{f}"
if os.path.isfile(path):
if path not in keep_list:
os.remove(path)
elif os.path.islink(path):
os.unlink(path)
elif os.path.isdir(path):
delete_files(keep_list, path)
files = os.listdir(curr_dir)
if not files:
os.rmdir(curr_dir)
答案 3 :(得分:0)
os.walk
路径:
import os
keep = set(['/a/a1/f1', '/b/b1/b2/f5', '/b/b3/f7'])
for dirpath, dirnames, filenames in os.walk('./'):
for name in filenames:
path = os.path.join(dirpath, name).lstrip('.')
print('check ' + path)
if path not in keep:
print('delete ' + path)
else:
print('keep ' + path)
除了通知你之外什么都不做。
它不认为os.walk
太慢,它让您可以选择保留正则表达式模式或任何其他标准。
答案 4 :(得分:0)
这里我得到了一个不同方面的解决方案,
假设我们在linux环境中,
首先,
find .
获取包含所有文件路径/文件夹的长列表
第二,假设我们得到了排除路径列表,为了排除您的卷(比如数千),我们可以将它们附加到上一个列表中,并且
| sort | uniq - c |grep -v "^2"
获取删除列表,
和第三
| xargs rm
实际进行删除