13.9 通过文件�查找文件¶

问题¶

你需�写一个涉�到文件查找�作的脚本,比如对日志归档文件的�命�工具, 你�想在Python脚本中调用shell,或者你�实现一些shell�能�的功能。

解决方案¶

查找文件,�使用 os.walk() 函数,传一个顶级目录�给它。 下�是一个例�,查找特定的文件�并答应所有符��件的文件全路径:

#!/usr/bin/env python3.3
import os

def findfile(start, name):
    for relpath, dirs, files in os.walk(start):
        if name in files:
            full_path = os.path.join(start, relpath, name)
            print(os.path.normpath(os.path.abspath(full_path)))

if __name__ == '__main__':
    findfile(sys.argv[1], sys.argv[2])

�存脚本为文件findfile.py,然�在命令行中执行它。 指定�始查找目录以��字作为�置�数,如下:

讨论¶

os.walk() 方法为我们�历目录树, �次进入一个目录,它会返回一个三元组,包�相对于查找目录的相对路径,一个该目录下的目录�列表, 以�那个目录下�的文件�列表。

对于�个元组,�需检测一下目标文件�是�在文件列表中。如果是就使用 os.path.join() �并路径。 为了��奇怪的路径�比如 ././foo//bar ,使用了�外两个函数�修正结果。 第一个是 os.path.abspath() ,它接�一个路径,�能是相对路径,最�返回�对路径。 第二个是 os.path.normpath() ,用�返回正常路径,�以解决�斜��对目录的多�引用的问题等。

尽管这个脚本相对于UNIX平�上�的很多查找�讲�简�很多,它还有跨平�的优势。 并且,还能很轻�的加入其他的功能。 我们�演示一个例�,下�的函数打�所有最近被修改过的文件:

#!/usr/bin/env python3.3

import os
import time

def modified_within(top, seconds):
    now = time.time()
    for path, dirs, files in os.walk(top):
        for name in files:
            fullpath = os.path.join(path, name)
            if os.path.exists(fullpath):
                mtime = os.path.getmtime(fullpath)
                if mtime > (now - seconds):
                    print(fullpath)

if __name__ == '__main__':
    import sys
    if len(sys.argv) != 3:
        print('Usage: {} dir seconds'.format(sys.argv[0]))
        raise SystemExit(1)

    modified_within(sys.argv[1], float(sys.argv[2]))

在此函数的基础之上,使用os,os.path,glob等类似模�,你就能实现更加��的�作了。 ��考5.11�节和5.13�节等相关章节。