python编程快速上手之第9章实践项目参考答案
本章介介绍了shutil,zipfile模块的使用,我们先来认识一下这2个模块吧。
一.shutil模块
shutil模块主要用于对文件或文件夹进行处理,包括:复制,移动,改名和删除文件,在shutil模块中主要以下这么几个函数:
1.复制文件和文件夹
shutil模块提供了2个函数:shutil.copy()和shutil.copytree()
shutil.copy的语法格式:
- copy(src, dst)
作用:
将src处的文件复制到dst路径中去,其中src,dst都是字符串形式的路径。如果dst是一个文件名,它将作为被复制文件的新名字,相当于把原路径的文件复制到新路径并改名。
举例:
将/etc/my.cnf 复制到/root/mysql中
- In []: import shutil
- In []: shutil.copy('/etc/my.cnf','/root/mysql/')
- Out[]: '/root/mysql/my.cnf'
- In []: ll /root/mysql/
- total
- -rw-r--r--. root Apr : my.cnf
将/etc/my.cnf复制到/root/mysql并改名为mysql.cnf
- In []: shutil.copy('/etc/my.cnf','/root/mysql/mysql.cnf')
- Out[]: '/root/mysql/mysql.cnf'
- In []: ll /root/mysql/
- total
- -rw-r--r--. root Apr : my.cnf
- -rw-r--r--. root Apr : mysql.cnf
shutil.copytree的语法格式:
- copytree(src, dst)
作用:
复制整个文件夹。将src处的文件夹,包括它的所有文件和子文件夹,复制到路径dst处的文件夹。返回一个新复制的文件夹路径的字符串。
举例:
- In []: shutil.copytree('/etc/yum.repos.d','/root/repo.back')
- Out[]: '/root/repo.back'
- In []: ll /root/drwxr-xr-x. root Apr repo.back/
- drwxr-xr-x. root Apr repo.bak/
注意:dst必须是一个系统中不存在目录,不然会报错:
- In [20]: shutil.copytree('/etc/yum.repos.d','/root/repo.bak')
FileExistsError: [Errno ] File exists: '/root/repo.bak'
2.文件和文件夹的移动和改名
shutil.move()
语法格式:
- move(stc,dst)
作用:
将路径stc处的文件夹移动到路径dst,并返回新位置的绝对路径的字符串。
举例:
将/root/目录下的a.txt移动到/root/test/目录中
- In []: shutil.move('/root/a.txt','/root/test/')
- Out[]: '/root/test/a.txt'
- In []: ll /root/test
- total
- -rw-r--r--. root Apr : a.txt
注意:
如果dst指向一个文件夹,src文件将移动到dst中,并保持原来的文件名,前提是dst必须是系统中已经存在的目录。
如果目标文件中已存在相同名称的文件将被覆盖,需要注意。
3.删除文件和文件夹
在os模块中:
os.remove(path)可以删除一个文件
os.rmdir(path)可以删除一个空文件夹。
在shutil模块中:
shutil.rmtree(path)可以删除一个文件夹及其所有的内容。
语法格式:
- os.rmdir(path)
- shutil.rmtree(path)
举例:
- In []: os.remove('/root/test/a.txt')
- In []: ll /root/test/
- total
- In []: shutil.move('/root/CentOS-Base.repo','/root/test/')
- Out[]: '/root/test/CentOS-Base.repo'
- In []: ll test
- total
- -rw-r--r--. root Apr CentOS-Base.repo
- In []: shutil.rmtree('/root/test')
- In []: ll
- total
- -rw-------. root Apr : anaconda-ks.cfg
- drwxr-xr-x. root Apr download/
- drwxr-xr-x. root Apr : mysql/
- drwxr-xr-x. root Apr : py34/
- drwxr-xr-x. root Apr : python/
- drwxr-xr-x. root Apr repo.back/
- drwxr-xr-x. root Apr repo.bak/
注意:
以上的删除都是永久的删除。为了安全起见最好使用send2trash第三方模块,它会将删除的文件放入回收站。在python3中已集成了这个模块。
send2trash用法:
- import send2trash
- send2trash(path)
二.遍历目录树
对文件的处理,尤其是批量操作就不得不对目录进行遍历。在python中os模块中的os.walk()函数就可以做到。
这个函数会递归遍历指定目录及子目录,返回一个3元组信息:当前目录名,子目录名,文件名,不包括 . 和 ..
常见用法:
- #!/usr/bin/env python3.4
- #coding:utf-8
- import os
- for foldName,subfolders,filenames in os.walk('/root/'):
- print('The current folder is: ' + foldName)
- for subfolder in subfolders:
- print('subfolder of ' + foldName + ':' + subfolder)
- for filename in filenames:
- print('file inside ' + foldName + ':' + filename)
- print('')
三.实践项目参考答案
- #!/usr/bin/env python3.4
- # coding:utf-8
- import os
- import shutil
- import send2trash
- # 9.8.1
- # 拷贝指定格式文件到指定目录,下面程序是将/etc目录下所的.conf文件拷贝到/root/test/目录里。
- src = '/etc/'
- dst = '/root/test/'
- ftype = '.conf'
- count = 0
- for filename in os.listdir(src):
- if filename.endswith(ftype):
- shutil.copy(src + filename,dst)
- count += 1
- print('文件 ' + src + filename + '\t被拷贝到---> ' + dst + ' 目录下')
- print("该目录下所有的 " + ftype + "文件已被拷贝到" + dst + "目录下")
- print('共拷贝了 ' + str(count) + ' 个文件')
- # 9.8.2
- # 搜索指定目录下大于100M的文件,打印出来并删除
- # 可以手动创建一个指定大小的空文件做试验
- # dd if=/dev/zero of=hello.txt bs=100M count=1
- for foldname,subfolders,filenames in os.walk(dst):
- for files in filenames:
- if os.path.getsize(dst + files) / 1024 /1024 > 100:
- print('大于100M的文件有:' + files + ' ' + str(os.path.getsize(dst + files) / 1024 / 1024) +'Mb')
- send2trash.send2trash(dst + files)
9.8.3
假设test文件夹下有如下文件,文件是以spam开头加上数字编号,但是编号并不连续有缺失,而且有的并不包含数字,我们需要找出不符合文件名的文件并重新命名成连续编号的文件名。
- (py34) [root@master test]# ls
- spam002.txt spam004.txt spam006.txt spam008.txt spam999.txt
- spam003.txt spam005.txt spam007.txt spam011.txt spamkkdf.txt
参考代码如下:
- #!/usr/bin/env python3.4
- # coding:utf-8
- import re
- import os
- fdir = '/root/python/py-9/test/'
- fdir_list = os.listdir(fdir)
- fdir_count = len(fdir_list)
- print(fdir_list)
- print('该目录下共有 %d 个文件' %fdir_count)
- f_pre = 'spam'
- f_num = []
- f_end = '.txt'
- fs_list = []
- # 这里只假定文件数量小100的情况
- for i in range(1,fdir_count + 1):
- if i < 10:
- f_name = f_pre + '' + str(i) + f_end
- f_num.append('' + str(i))
- fs_list.append(f_name)
- else:
- f_name = f_pre + '' + str(i) + f_end
- f_num.append('' + str(i))
- fs_list.append(f_name)
- max_f_num = max(f_num)
- print('该目录下文件最大的编号应该是: %s' %max_f_num)
- print('正确的文件名应该是:')
- print(fs_list)
- # 使用正则表达式搜索目录中已有编号的文件并存入列表yf_num中
- re_num = '\d{3}'
- yf_num = re.findall(f_pre + re_num + f_end,' '.join(fdir_list))
- ra_num = re.findall(re_num,' '.join(fdir_list))
- print('目录中已有编号文件:\n%s' %yf_num)
- # fq_list为目录中缺失编号的文件名列表
- # fx_list为当前目录中需要修改名称的文件列表
- fq_list = []
- fx_list = []
- # 定位缺失的编号文件并放入列表中
- for a in fs_list:
- if a not in yf_num:
- fq_list.append(a)
- print('缺少的文件编号是:\n%s' %fq_list)
- # 查找目录中没有编号或不正连续的编号文件并放入列表中
- for f_rename in fdir_list:
- if f_rename not in fs_list:
- fx_list.append(f_rename)
- print('需要修改的文件名有:\n%s' %fx_list)
- # 更改文件名
- for k in fq_list:
- for v in fx_list:
- os.rename(fdir + v,fdir + k)
- # 每当修完一个文件名应该更新一下这个列表
- fx_list.remove(v)
- print('改完名后的结果为:')
- os.system('ls')
今天回来看看,决定用函数的方式来练习并实现,代码有了一些小的改进,上代码:
- #!/usr/bin/env python3.4
- # coding:utf-8
- import re
- import os
- fdir = '/root/github/shell/python3/py-9/test/'
- fdir_list = os.listdir(fdir)
- fdir_f_count = len(fdir_list)
- print('当前目录的文件为:\n%s' % fdir_list)
- def getFileformat(f_pre,f_num,f_end):
- fileformat = f_pre + f_num + f_end
- return fileformat
- file_list = []
- def getTruefile():
- for i in range(1,fdir_f_count + 1):
- if i < 10:
- f_format = getFileformat('spam','' + str(i),'.txt')
- file_list.append(f_format)
- else:
- f_format = getFileformat('spam','' + str(i),'.txt')
- file_list.append(f_format)
- return file_list
- truefilelist = getTruefile()
- print('正确的文件编号应该是:\n%s' %truefilelist)
- lostnumfilelist = []
- def getLostnumfile(fdirlist,truelist):
- for lf in truelist:
- if lf not in fdirlist:
- lostnumfilelist.append(lf)
- return lostnumfilelist
- lostnumfile = getLostnumfile(fdir_list,file_list)
- print('缺失的文件编号为:\n%s' %lostnumfile)
- renamelist = []
- def getrenamefile(fdirlist,func):
- for a in fdirlist:
- if a not in func:
- renamelist.append(a)
- return renamelist
- renamefilelist = getrenamefile(fdir_list,file_list)
- print('需要修改的文件是\n%s' %renamefilelist)
- def renamefile(func1,func2):
- for b in func1:
- for c in func2:
- os.rename(fdir + c,fdir + b)
- func2.remove(c)
- rename = renamefile(lostnumfile,renamefilelist)
- os.chdir(fdir)
- print('修改后的结果为:')
- os.system('ls')
python编程快速上手之第9章实践项目参考答案的更多相关文章
- python编程快速上手之第10章实践项目参考答案
本章主要讲了python程序的调试,当程序有BUG或异常的时候,我们如何调试代码找出问题点.其实在本章之前的章节我们做练习的时候都会遇到各种各样的错语和异常,最初当不知道程序哪里出错的情况下不可否 ...
- python编程快速上手之第8章实践项目参考答案
第8章实践项目之疯狂填词 创建一个一个疯狂填词(Mad Libs),程序,它将读入文本文件,并让用户在该文本文件中出现 ADJECTIVE,NOUN,VERB等单词的地方,加上他们自己的文本. 首先准 ...
- python编程快速上手之第5章实践项目参考答案
#!/usr/bin/env python3.5 # coding:utf-8 # 5.6.1 # 好玩游戏的物品清单 # 给定一个字典,包含物品名称和数量,并打印出数量对应的物品 dict_stuf ...
- python编程快速上手之第3章实践项目参考答案
1 #!/usr/bin/env python 2 # coding:utf-8 3 # write by mfyang 4 # collatz.py 5 # 从用户读入一个值,并判断这个值是不是一个 ...
- python编程快速上手之第7章实践项目参考答案
#!/usr/bin/env python3.5 #coding:utf-8 import re # 7.18.1 # 强口令检测 # 写一个函数,使用正则表达式,确保传入的口令字符串是强口令 # 长 ...
- python编程快速上手之第6章实践项目参考答案
#!/usr/bin/env python3.5 2 #coding:utf-8 3 # 4 # 这个项目主要目的是字符串的处理,简单格式化输出 5 tableData = [['apples','o ...
- python编程快速上手之第4章实践项目参考答案
#!/usr/bin/env python3.5 # coding:utf-8 # 假定有一个列表,编写函数以一个列表值作为参数,返回一个字条串 # 该字符串包含所有表项,之间以逗号和空格分隔,并在最 ...
- Python 编程快速上手 第十四章 处理 CSV 文件和 JSON 数据
前言 这一章分为两个部分,处理 CSV 格式的数据和处理 JSON 格式个数据. 处理 CSV 理解 csv csv 的每一行代表了电子表格中的每一行,每个逗号分开两个单元格csv 的内容全部为文本, ...
- Python 编程快速上手 第十五章 保持时间,计划任务和启动程序
前言 这一章节的主要内容是: 处理时间类型的数据(使用python 的两个模块: time 和 datetime 来处理) 创建多个线程 (使用 threading 模块来创建多个线程) 进行多个进程 ...
随机推荐
- 挂载mount
mount 1 挂载mount 基本概念 挂载:将额外文件系统与根文件系统现存的目录建立起关联关系,进而使得此目录做为其它文件访问入库的行为 卸载:为解除关联关系的过程 注意:挂载点下原有的文件在挂载 ...
- nodeJS之路径PATH模块
前面的话 path模块包含一系列处理和转换文件路径的工具集,通过 require('path') 可用来访问这个模块.本文将详细介绍path模块 路径组成 [path.dirname(p)] 返回路径 ...
- 初识Java-IO流
1.定义: 流是一种抽象概念,它代表了数据的无结构化传递.数据流(Stream)是指数据通信的通道. 2.流的分类: 1)按流向分 输入流:从数据源到程序中的流 输出流:从程序到数据源的流 2)按数据 ...
- 一键帮你复制多个文件到多个机器——PowerShell小脚本(内附PS远程执行命令问题解析)
作为一个后台程序猿,经常需要把一堆程序集(DLL)或者应用程序(EXE)复制到多个服务器上,实现程序的代码逻辑更新,用以测试新的功能或改动逻辑.这里给大家介绍一个自己实现的PowerShell脚本,方 ...
- htm语言的语法基础及规则
HTML的主要语法是元素和标签.元素是符合DTD(文档类型定义)的文档组成部分,如title(文档标题).IMG(图象).table(表格)等等.元素名不区分大小写的.HTML用标签来规定元素的属性和 ...
- CoreAnimation学习,学习总结,记录各种过程中遇到的坑
1. CAAimation 的 duration = 0 的时候, 这个时候就相当于没有动画了. 2. CAKeyframeAnimation *rotateAnimation = [CAKeyfr ...
- android蓝牙学习
学习路线 1 蓝牙权限 <uses-permission android:name="android.permission.BLUETOOTH" /> <uses ...
- JavaScript函数之递归
递归 递归的本质就是使用函数自身来解决问题的思路. 递归的定义(摘): 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明 ...
- 聊聊RocksDB Compact
| 导语 对于 LevelCompact 策略,RocksDB会根据每一层不同的策略计算出CompactScore,根据CompactScore大小来决定那一层将会优先进行Compact,然后选择Le ...
- 总结·CSS3中定位模型之position属性的使用方法
一.position元素介绍 position属性规定了元素的定位类型,通过定位,可准确地定义元素相对于其正常位置而应该出现的位置,或者是相对于父元素.另一元素和浏览器窗口等的位置. position ...