Python:如何使用“listfiles”的输出来删除/移动/等文件

时间:2016-06-10 10:08:23

标签: python list directory delete-file os.walk

背景

我的目标是在两个不同的文件夹中找到dublicate文件(没有子文件夹)。为此,我使用以下Python脚本:

###Check ob alle Archive noch vorhanden oder ob Daten bei Check gelöscht wurden
def listfiles(path):
    files = []
    for dirName, subdirList, fileList in os.walk(path):
        dir = dirName.replace(path, '')
        for fname in fileList:
                if fname.endswith("_GIS.7z"):
                    files.append(os.path.join(dir, fname))
    return files

x = listfiles(root)
y = listfiles(backupfolderGIS)

#q = [filename for filename in x if filename not in y]

files_only_in_x = set(x) - set(y) 
files_only_in_y = set(y) - set(x)
files_only_in_either = set(x) ^ set(y)
files_in_both = set(x) & set(y)
all_files = set(x) | set(y)

print "Alle Datein:"
print all_files
print " "

print "Nur im Zwischenspeicher:"
print files_only_in_x
print " "

print "Nur im Backupordner:"
print files_only_in_y
print " "

print "Nur einem von beiden Ordnern:"
print files_only_in_either
print " "

print "In beiden Ordnern:"
print files_in_both
print " "

相关的输出变量/列表是files_in_both(文件夹);它向我展示了这些共和党人;如果我使用print,则看起来像set(['NameoftheProject_GIS.7z', 'NameofanotherProject_GIS.7z'])

问题:

如何使用此输出/信息(目录中的dublicate文件)删除/移动它们?例如,文件夹NameoftheProject_GIS.7z / list NameofanotherProject_GIS.7z中的文件backupfolderGISfiles_in_both

1 个答案:

答案 0 :(得分:-1)

os.walk递归检查从您传递的根目录开始的所有文件夹和子文件夹,您要检查两个不同的文件夹(不包含子文件夹),以便只使用 glob搜索每个文件夹,如果您想移动,可以使用shutil.move

from glob import iglob
from os import path
from shutil import move

pt1, pt2 = "/path_1", "path_2"
dupe = set(map(path.basename, iglob("/path_1./*_GIS.7z"))).intersection(map(path.basename, iglob("/path_2./*_GIS.7z")))

for fle in dupe:
    # move(src, dest)
    move(path.join(pt1, fle), "wherever")

或删除使用os.remove

for fle in dupe:
    os.remove(path.join(pt1, fle))

如果要从pt2移动/删除文件,请将其传递给path.join代替pt1。

您还可以将 str.endwith os.listdir

一起使用
dupe = set(fname for fname in os.listdir(pt1) if fname.endswith("_GIS.7z")).intersection(fname for fname in os.listdir(pt2) if fname.endswith("_GIS.7z"))

为了避免重复,你可以把它放在一个函数中:

from shutil import move
from os import path, listdir
def listfiles(path, end):
    return set(fname for fname in listdir(path) if fname.endswith(end))

for fle in listfiles(pt1,"_GIS.7z").intersection(listfiles(pt2, "_GIS.7z")):
    move(path.join(t1, fle), "wherever")

现在,如果您确实要检查所有文件夹中是否有相同基本名称的文件以及dupe名称的内容,则需要保留完整路径的记录,您可以使用{{3为基本名称对所有公共文件进行分组}}:

from os import path, walk
from collections import defaultdict

def listfiles(pth, end):
    files = defaultdict(list)
    for dirName, subdirList, fileList in walk(pth):
        for fname in fileList:
            if fname.endswith(end):
                files[fname].append(path.join(dirName, fname))
    return files

您将获得一个dict,其中键是基本名称,值是文件列表,每个文件都有完整路径,任何包含多个vaulue的列表意味着您至少有两个具有相同名称的文件,但您应该记住具有相同的基名并不意味着文件实际上是相同的。