使用Python删除目录中的所有文件

169
我想在一个目录中删除所有扩展名为.bak的文件。我该如何使用Python实现?

2
请注意:要删除整个目录树,可以使用 shutil.rmtree(path) - jfs
可能是一个重复问题,关于如何在Python中删除文件夹内容?(https://dev59.com/5nVC5IYBdhLWcg3wykQt) - FabioSpaghetti
9个回答

318

通过 os.listdiros.remove

import os

filelist = [ f for f in os.listdir(mydir) if f.endswith(".bak") ]
for f in filelist:
    os.remove(os.path.join(mydir, f))

仅使用单个循环:

for f in os.listdir(mydir):
    if not f.endswith(".bak"):
        continue
    os.remove(os.path.join(mydir, f))

或者通过 glob.glob 进行操作:

import glob, os, os.path

filelist = glob.glob(os.path.join(mydir, "*.bak"))
for f in filelist:
    os.remove(f)

请确保处于正确的目录中,可以使用os.chdir函数进行切换。


22
你的第一个例子使用了冗余的循环。你可以使用一次循环 - [ os.remove(f) for f in os.listdir(".") if f.endswith(".bak") ] - 因为列表推导式的设计就是如此。或者你可以将列表推导式中的“if”移到for循环中 - for f in os.listdir("."): if f.endswith(".bak"): os.remove(f) - dragonjujo
@slh2080,既然您说问题已经解决,为什么不将答案标记为正确答案呢? - blwy10
6
小心使用os.listdir(".")!!!我曾经使用这段代码,却忘记更改路径,结果所有的代码都不见了!!尝试了两种恢复工具但都没有成功!! - Lei Guo
@LeiGuo 已修复。 - yugr
@dragonjujo 我认为,调用副作用与列表推导式的使用方式非常不相符。 - marcelm
相当确定第二个例子有一个“not”太多了! - Xanlantos

28
在Python 3.5中,如果你需要检查文件属性或类型,使用os.scandir会更好 - 请查看os.DirEntry以获取返回的对象的属性。
import os 

for file in os.scandir(path):
    if file.name.endswith(".bak"):
        os.unlink(file.path)

由于每个DirEntry已经包含文件的完整路径,因此这也不需要更改目录。


你缺少了一个冒号,for循环内的第一行应该是if file.name.endswith(".bak"): - TSeymour
谢谢!这会教会我写代码时不要忘了实际运行。 - Yi Jiang
嗨,如何创建路径对象? - Vandit Shah

26

使用os.chdir更改目录。 使用glob.glob生成以'.bak'结尾的文件名列表。 列表的元素仅为字符串。

然后您可以使用os.unlink删除文件。(PS.os.unlinkos.remove是同义词)

#!/usr/bin/env python
import glob
import os
directory='/path/to/dir'
os.chdir(directory)
files=glob.glob('*.bak')
for filename in files:
    os.unlink(filename)

8

您可以创建一个函数。添加最大深度以遍历子目录。

def findNremove(path,pattern,maxdepth=1):
    cpath=path.count(os.sep)
    for r,d,f in os.walk(path):
        if r.count(os.sep) - cpath <maxdepth:
            for files in f:
                if files.endswith(pattern):
                    try:
                        print "Removing %s" % (os.path.join(r,files))
                        #os.remove(os.path.join(r,files))
                    except Exception,e:
                        print e
                    else:
                        print "%s removed" % (os.path.join(r,files))

path=os.path.join("/home","dir1","dir2")
findNremove(path,".bak")

2

首先使用glob查找它们,然后删除它们。


1

我知道这篇文章有点旧了,但是下面是如何仅使用os模块来实现...

def purgedir(parent):
    for root, dirs, files in os.walk(parent):                                      
        for item in files:
            # Delete subordinate files                                                 
            filespec = os.path.join(root, item)
            if filespec.endswith('.bak'):
                os.unlink(filespec)
        for item in dirs:
            # Recursively perform this operation for subordinate directories   
            purgedir(os.path.join(root, item))

0

对于一行解决方案(适用于WindowsLinux);

import glob,os

for file in glob.glob("<your_path>/*.bak"): print(file," these will be deleted")

if input("continue ?") == "Y":
    for file in glob.glob("<your_path>/*.bak"): os.remove(file)

0
或者使用pathlib.Path:
from pathlib import Path

for file in Path("/path/to/folder").glob("*"):
    file.unlink()

这样,我们还可以指定只删除与通配符模式匹配的文件。例如:.glob("*.txt") 只删除文本文件。
而对于递归删除子文件夹中的所有文件,只需使用 rglob 替代 glob。以下代码将删除指定文件夹及其所有子文件夹中的所有 txt 文件:
for file in Path("/path/to/folder").rglob("*.txt"):
    file.unlink()

-2

在Linux和macOS上,您可以在shell中运行简单的命令:

subprocess.run('rm /tmp/*.bak', shell=True)

4
我认为这不是一个好选择。它不便携,并且可能会更昂贵,因为需要额外的子进程。最好使用Python API。 - Haakon
2
这个解决方案依赖于特定平台,而Python则是跨平台的。 - Hamza Rashid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接