删除目录中每个文件的算法,但给定列表中的某些文件除外

时间:2016-05-03 16:18:24

标签: python regex algorithm perl

假设我们有一个像这样的结构的目录,我将目录标记为(+),将文件标记为( - )

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编写的程序。

有人可以提出建议吗?

谢谢你,并致以最诚挚的问候。

亚历

5 个答案:

答案 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

实际进行删除