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å°�节ç‰ç›¸å…³ç« 节。