“Python 目录管理”的版本间的差异
(→遍历目录内容) |
(→深度遍历) |
||
(未显示2个用户的30个中间版本) | |||
第1行: | 第1行: | ||
+ | ==背景介绍== | ||
+ | *寻找‘危险’文件 | ||
+ | *寻找大文件 | ||
+ | *比较两个目录 | ||
+ | *深度遍历目录 | ||
+ | *统计目录占用空间 | ||
+ | |||
==引入模块== | ==引入模块== | ||
import os | import os | ||
第11行: | 第18行: | ||
===创建目录=== | ===创建目录=== | ||
− | + | >>> t=os.getcwd()+"\\temp2" | |
− | 创建多级目录 os. | + | >>> os.mkdir(t) |
+ | |||
+ | 创建多级目录 os.makedirs(r"c:\python\test") | ||
===切换目录=== | ===切换目录=== | ||
第30行: | 第39行: | ||
<nowiki>['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'temp', 'Tools', 'vcruntime140.dll']</nowiki> | <nowiki>['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'temp', 'Tools', 'vcruntime140.dll']</nowiki> | ||
+ | 案例:寻找‘危险’文件: | ||
+ | |||
+ | 链接:[https://zhidao.baidu.com/question/1767049318342072660.html 危险文件有哪些 ?] | ||
+ | |||
+ | <nowiki> | ||
+ | import os | ||
+ | for fname in os.listdir(r'd:\\654'): | ||
+ | if fname.endswith(('.exe','.com','.pif','.bat','.scr')): | ||
+ | print('发现危险文件 ',fname)</nowiki> | ||
+ | |||
+ | ====改进版1:建立危险文件库==== | ||
+ | <nowiki> | ||
+ | import os | ||
+ | store = ('.exe','.txt') | ||
+ | for fname in os.listdir(r'd:\\'): | ||
+ | if fname.endswith(store): | ||
+ | print('发现危险文件 ',fname)</nowiki> | ||
+ | |||
+ | ====改进版2:列表推导式==== | ||
>>> [fname for fname in os.listdir('.')if fname.endswith(('.exe', '.txt'))] | >>> [fname for fname in os.listdir('.')if fname.endswith(('.exe', '.txt'))] | ||
['LICENSE.txt', 'NEWS.txt', 'python.exe', 'pythonw.exe'] | ['LICENSE.txt', 'NEWS.txt', 'python.exe', 'pythonw.exe'] | ||
− | + | 列表推导式 详见:[[Python列表]] | |
− | + | 应用:[[Python实例:制作图片电子书]] | |
− | |||
− | + | ===删除目录=== | |
+ | >>> os.listdir('.') | ||
− | + | <nowiki>['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'temp', 'Tools', 'vcruntime140.dll']</nowiki> | |
+ | |||
+ | >>> os.rmdir('temp') | ||
+ | |||
+ | >>> os.listdir('.') | ||
+ | |||
+ | <nowiki>['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'Tools', 'vcruntime140.dll']</nowiki> | ||
− | + | ===查看目录空间占用情况=== | |
+ | 查看某文件大小: | ||
− | + | >>> os.path.getsize(r'd://pythonw.exe') | |
− | + | 98320 | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | 以兆为单位查看: | |
− | + | os.path.getsize(r"D:\teaching\自动化运维\练习\data_etr.csv")/1024/1024 | |
− | |||
− | + | 案例:计算单层目录占用空间 | |
− | <nowiki> | + | <nowiki> |
− | + | import os | |
+ | mydir = '.' | ||
+ | total =0 | ||
+ | for fname in os.listdir(mydir): | ||
− | + | sub_path = os.path.join(mydir, fname)#获得每个文件路径 | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | = | + | if os.path.isfile(sub_path): |
− | + | ||
+ | size =(os.path.getsize(sub_path))/1024/1024 #换算成MB | ||
− | + | total +=size | |
− | + | print("该目录所有文件占据:"+str(total)+"MB 空间")</nowiki> | |
− | + | 案例:寻找大文件! | |
− | |||
− | + | <nowiki> | |
− | + | import os | |
− | + | mydir = r'D:\Game\2020校赛' | |
− | + | for fname in os.listdir(mydir): | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | = | + | sub_path = os.path.join(mydir, fname) |
− | |||
− | + | if os.path.isfile(sub_path): | |
− | + | size =(os.path.getsize(sub_path))/1024 #换算成KB | |
− | > | + | if size >100: |
− | + | print(fname,":",size,"KB") | |
+ | </nowiki> | ||
− | + | 输出结果: | |
− | > | + | |
+ | <nowiki>LICENSE.txt | ||
+ | NEWS.txt | ||
+ | python.exe | ||
+ | pythonw.exe</nowiki> | ||
− | + | 改进版:寻找D盘大于500M的文件 | |
− | > | + | <nowiki> |
+ | import os | ||
+ | mydir = r'D:\\' | ||
+ | emit_dir ={"System Volume Information","Config.Msi","Program Files","$RECYCLE.BIN"} | ||
+ | def findBig(dir): | ||
+ | for fname in os.listdir(dir): | ||
− | + | sub_path = os.path.join(dir, fname) | |
− | + | if os.path.isfile(sub_path): | |
− | + | size =(os.path.getsize(sub_path))/1024/1024 #换算成MB | |
− | + | if size>500: | |
+ | size =round(size,2) | ||
+ | print(sub_path,":",size,"MB") | ||
+ | elif fname not in emit_dir: | ||
+ | findBig(sub_path) | ||
− | + | if __name__ == "__main__" : | |
− | + | findBig(mydir)</nowiki> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
===比较两个目录=== | ===比较两个目录=== | ||
第150行: | 第165行: | ||
调用: | 调用: | ||
− | import filecmp | + | <nowiki>import filecmp |
− | + | a =r"D:\teaching\自动化运维\2021-2022-2\上星期" | |
− | a = " | + | b =r"D:\teaching\自动化运维\2021-2022-2\这星期" |
− | + | dirobj =filecmp.dircmp(a,b) | |
− | b = " | + | print(dirobj.report())</nowiki> |
− | |||
− | dirobj = filecmp.dircmp(a, b | ||
− | |||
输出对比结果: | 输出对比结果: | ||
第179行: | 第191行: | ||
left_only:['data.txt'] | left_only:['data.txt'] | ||
right_only:['data_asc.txt']</nowiki> | right_only:['data_asc.txt']</nowiki> | ||
+ | |||
+ | ==遍历目录下所有子目录和文件== | ||
+ | ===深度遍历=== | ||
+ | |||
+ | [[文件:python2020-7-2.png|500px]] | ||
+ | |||
+ | 递归:[[Python函数的递归]] | ||
+ | |||
+ | <nowiki>from os import listdir | ||
+ | from os.path import join, isfile, isdir | ||
+ | |||
+ | def listDirDepthFirst(directory): | ||
+ | '''深度优先遍历文件夹''' | ||
+ | #遍历文件夹,如果是文件就直接输出 | ||
+ | #如果是文件夹,就输出显示,然后递归遍历该文件夹 | ||
+ | for subPath in listdir(directory): | ||
+ | path = join(directory, subPath)#【绝对路径】 | ||
+ | if isfile(path):#【判断是否是文件】 | ||
+ | print(path) | ||
+ | elif isdir(path):#【判断是否是目录】 | ||
+ | print(path) | ||
+ | listDirDepthFirst(path) | ||
+ | |||
+ | if __name__ =='__main__': | ||
+ | listDirDepthFirst(r'D:\teaching\自动化运维\2021-2022-2')</nowiki> | ||
+ | |||
+ | 案例:实现文件的搜索功能 | ||
+ | |||
+ | <nowiki> | ||
+ | from os import listdir | ||
+ | from os.path import join, isfile, isdir | ||
+ | def listDirDepthFirst(directory,keyword): | ||
+ | '''深度优先遍历文件夹''' | ||
+ | #在特定目录搜索带关键字的文件 | ||
+ | for subPath in listdir(directory): | ||
+ | path = join(directory, subPath)#【绝对路径】 | ||
+ | if isfile(path) :#【判断是否是文件】 | ||
+ | if keyword in path: | ||
+ | print(path) | ||
+ | elif isdir(path):#【判断是否是目录】 | ||
+ | #print(path) | ||
+ | listDirDepthFirst(path,keyword) | ||
+ | |||
+ | if __name__ =='__main__': | ||
+ | while True: | ||
+ | keyword = input("请输入查找关键字:") | ||
+ | listDirDepthFirst('.',keyword)</nowiki> | ||
+ | ===广度遍历=== | ||
+ | [[文件:python2020-7-3.png]] | ||
+ | |||
+ | [[文件:python2020-7-1.png]] | ||
+ | |||
+ | 下面的代码使用了广度优先遍历方法。 | ||
+ | |||
+ | <nowiki> | ||
+ | from os import listdir | ||
+ | from os.path import join, isfile, isdir | ||
+ | |||
+ | def listDirWidthFirst(directory): | ||
+ | '''广度优先遍历文件夹''' | ||
+ | #使用列表模拟双端队列,效率稍微受影响,不过关系不大 | ||
+ | dirs = [directory]#这个directory就是列表的第一个元素 | ||
+ | #如果还有没遍历过的文件夹,继续循环 | ||
+ | while dirs: | ||
+ | #遍历还没遍历过的第一项 | ||
+ | current = dirs.pop(0) | ||
+ | #遍历该文件夹,如果是文件就直接输出显示 | ||
+ | #如果是文件夹,输出显示后,标记为待遍历项 | ||
+ | for subPath in listdir(current): | ||
+ | path = join(current, subPath) | ||
+ | if isfile(path): | ||
+ | print(path) | ||
+ | elif isdir(path): | ||
+ | print(path) | ||
+ | dirs.append(path) | ||
+ | |||
+ | if __name__ =='__main__': | ||
+ | listDirWidthFirst(r'D:\teaching\自动化运维\2021-2022-2') | ||
+ | </nowiki> | ||
+ | |||
==应用:统计目录占用空间== | ==应用:统计目录占用空间== | ||
+ | 本程序为目录管理的一个典型应用, | ||
+ | |||
+ | 对统计电脑中每个文件夹(目录)占用空间的大小。 | ||
+ | |||
+ | 除了应用目录管理有关命令外,还用到了递归思想 和 函数调用的有关知识,请仔细体会。 | ||
+ | |||
+ | 关于递归思想,这里有一个小讲义:[[Python函数的递归]],大家不清楚递归的 可以看一下。 | ||
<nowiki>import os | <nowiki>import os | ||
第188行: | 第287行: | ||
dirNum = 0 | dirNum = 0 | ||
+ | #统计函数,递归的遍历每个文件夹 | ||
def visitDir(path): | def visitDir(path): | ||
global totalSize | global totalSize | ||
第201行: | 第301行: | ||
visitDir(sub_path) #递归遍历子文件夹 | visitDir(sub_path) #递归遍历子文件夹 | ||
+ | #主函数 | ||
def main(path): | def main(path): | ||
if not os.path.isdir(path): | if not os.path.isdir(path): | ||
第207行: | 第308行: | ||
visitDir(path) | visitDir(path) | ||
+ | #单位换算函数 | ||
def sizeConvert(size): #单位换算 | def sizeConvert(size): #单位换算 | ||
K, M, G = 1024, 1024**2, 1024**3 | K, M, G = 1024, 1024**2, 1024**3 | ||
第218行: | 第320行: | ||
return str(size)+'Bytes' | return str(size)+'Bytes' | ||
+ | #输出函数 | ||
def output(path): | def output(path): | ||
print('The total size of '+path+' is:'+sizeConvert(totalSize) | print('The total size of '+path+' is:'+sizeConvert(totalSize) |
2023年2月28日 (二) 01:16的最新版本
目录
背景介绍
- 寻找‘危险’文件
- 寻找大文件
- 比较两个目录
- 深度遍历目录
- 统计目录占用空间
引入模块
import os
import filecmp
具体操作
查看当前目录
>>> os.getcwd() 'C:\\Users\\maxin\\AppData\\Local\\Programs\\Python\\Python37' >>>
创建目录
>>> t=os.getcwd()+"\\temp2"
>>> os.mkdir(t)
创建多级目录 os.makedirs(r"c:\python\test")
切换目录
>>> os.chdir(os.getcwd()+'\\temp')
>>> os.getcwd()
'C:\\Users\\maxin\\AppData\\Local\\Programs\\Python\\Python37\\temp'
>>> os.chdir('..')
遍历目录内容
>>> os.listdir('.')
>>> os.listdir(r'D:\teaching\自动化运维\练习')
['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'temp', 'Tools', 'vcruntime140.dll']
案例:寻找‘危险’文件:
链接:危险文件有哪些 ?
import os for fname in os.listdir(r'd:\\654'): if fname.endswith(('.exe','.com','.pif','.bat','.scr')): print('发现危险文件 ',fname)
改进版1:建立危险文件库
import os store = ('.exe','.txt') for fname in os.listdir(r'd:\\'): if fname.endswith(store): print('发现危险文件 ',fname)
改进版2:列表推导式
>>> [fname for fname in os.listdir('.')if fname.endswith(('.exe', '.txt'))]
['LICENSE.txt', 'NEWS.txt', 'python.exe', 'pythonw.exe']
列表推导式 详见:Python列表
删除目录
>>> os.listdir('.')
['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'temp', 'Tools', 'vcruntime140.dll']
>>> os.rmdir('temp')
>>> os.listdir('.')
['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'Tools', 'vcruntime140.dll']
查看目录空间占用情况
查看某文件大小:
>>> os.path.getsize(r'd://pythonw.exe')
98320
以兆为单位查看:
os.path.getsize(r"D:\teaching\自动化运维\练习\data_etr.csv")/1024/1024
案例:计算单层目录占用空间
import os mydir = '.' total =0 for fname in os.listdir(mydir): sub_path = os.path.join(mydir, fname)#获得每个文件路径 if os.path.isfile(sub_path): size =(os.path.getsize(sub_path))/1024/1024 #换算成MB total +=size print("该目录所有文件占据:"+str(total)+"MB 空间")
案例:寻找大文件!
import os mydir = r'D:\Game\2020校赛' for fname in os.listdir(mydir): sub_path = os.path.join(mydir, fname) if os.path.isfile(sub_path): size =(os.path.getsize(sub_path))/1024 #换算成KB if size >100: print(fname,":",size,"KB")
输出结果:
LICENSE.txt NEWS.txt python.exe pythonw.exe
改进版:寻找D盘大于500M的文件
import os mydir = r'D:\\' emit_dir ={"System Volume Information","Config.Msi","Program Files","$RECYCLE.BIN"} def findBig(dir): for fname in os.listdir(dir): sub_path = os.path.join(dir, fname) if os.path.isfile(sub_path): size =(os.path.getsize(sub_path))/1024/1024 #换算成MB if size>500: size =round(size,2) print(sub_path,":",size,"MB") elif fname not in emit_dir: findBig(sub_path) if __name__ == "__main__" : findBig(mydir)
比较两个目录
filecmp模块能够实现两个文件夹的比较。
背景
test1目录:data.txt、sample.txt
test2目录:data_asc.txt、sample.txt
使用方法
调用:
import filecmp a =r"D:\teaching\自动化运维\2021-2022-2\上星期" b =r"D:\teaching\自动化运维\2021-2022-2\这星期" dirobj =filecmp.dircmp(a,b) print(dirobj.report())
输出对比结果:
dirobj.report() # report(),比较当前指定目录中的内容
diff test1 test2 Only in test1 : ['data.txt'] Only in test2 : ['data_asc.txt'] Identical files : ['sample.txt']
输出分类对比结果
print("common:"+str(dirobj.common)) # common,两边目录共同存在的文件或目录
print("left_only:"+str(dirobj.left_only)) # 只在左目录中的文件或目录
print("right_only:"+str(dirobj.right_only)) # 只在右边目录中的文件或目录
common:['sample.txt'] left_only:['data.txt'] right_only:['data_asc.txt']
遍历目录下所有子目录和文件
深度遍历
递归:Python函数的递归
from os import listdir from os.path import join, isfile, isdir def listDirDepthFirst(directory): '''深度优先遍历文件夹''' #遍历文件夹,如果是文件就直接输出 #如果是文件夹,就输出显示,然后递归遍历该文件夹 for subPath in listdir(directory): path = join(directory, subPath)#【绝对路径】 if isfile(path):#【判断是否是文件】 print(path) elif isdir(path):#【判断是否是目录】 print(path) listDirDepthFirst(path) if __name__ =='__main__': listDirDepthFirst(r'D:\teaching\自动化运维\2021-2022-2')
案例:实现文件的搜索功能
from os import listdir from os.path import join, isfile, isdir def listDirDepthFirst(directory,keyword): '''深度优先遍历文件夹''' #在特定目录搜索带关键字的文件 for subPath in listdir(directory): path = join(directory, subPath)#【绝对路径】 if isfile(path) :#【判断是否是文件】 if keyword in path: print(path) elif isdir(path):#【判断是否是目录】 #print(path) listDirDepthFirst(path,keyword) if __name__ =='__main__': while True: keyword = input("请输入查找关键字:") listDirDepthFirst('.',keyword)
广度遍历
下面的代码使用了广度优先遍历方法。
from os import listdir from os.path import join, isfile, isdir def listDirWidthFirst(directory): '''广度优先遍历文件夹''' #使用列表模拟双端队列,效率稍微受影响,不过关系不大 dirs = [directory]#这个directory就是列表的第一个元素 #如果还有没遍历过的文件夹,继续循环 while dirs: #遍历还没遍历过的第一项 current = dirs.pop(0) #遍历该文件夹,如果是文件就直接输出显示 #如果是文件夹,输出显示后,标记为待遍历项 for subPath in listdir(current): path = join(current, subPath) if isfile(path): print(path) elif isdir(path): print(path) dirs.append(path) if __name__ =='__main__': listDirWidthFirst(r'D:\teaching\自动化运维\2021-2022-2')
应用:统计目录占用空间
本程序为目录管理的一个典型应用,
对统计电脑中每个文件夹(目录)占用空间的大小。
除了应用目录管理有关命令外,还用到了递归思想 和 函数调用的有关知识,请仔细体会。
关于递归思想,这里有一个小讲义:Python函数的递归,大家不清楚递归的 可以看一下。
import os totalSize = 0 fileNum = 0 dirNum = 0 #统计函数,递归的遍历每个文件夹 def visitDir(path): global totalSize global fileNum global dirNum for lists in os.listdir(path): sub_path = os.path.join(path, lists) if os.path.isfile(sub_path): fileNum = fileNum+1 #统计文件数量 totalSize = totalSize+os.path.getsize(sub_path) #统计文件总大小 elif os.path.isdir(sub_path): dirNum = dirNum+1 #统计文件夹数量 visitDir(sub_path) #递归遍历子文件夹 #主函数 def main(path): if not os.path.isdir(path): print('Error:"', path, '" is not a directory or does not exist.') return visitDir(path) #单位换算函数 def sizeConvert(size): #单位换算 K, M, G = 1024, 1024**2, 1024**3 if size >= G: return str(size/G)+'G Bytes' elif size >= M: return str(size/M)+'M Bytes' elif size >= K: return str(size/K)+'K Bytes' else: return str(size)+'Bytes' #输出函数 def output(path): print('The total size of '+path+' is:'+sizeConvert(totalSize) +'('+str(totalSize)+' Bytes)') print('The total number of files in '+path+' is:',fileNum) print('The total number of directories in '+path+' is:',dirNum) if __name__=='__main__': path = r'D:\teaching\自动化运维' main(path) output(path)
应用:复制空目录
云盘备份:有的时候需要将云端的目录结构复制到本地