本章介介绍了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章实践项目参考答案的更多相关文章

  1. python编程快速上手之第10章实践项目参考答案

      本章主要讲了python程序的调试,当程序有BUG或异常的时候,我们如何调试代码找出问题点.其实在本章之前的章节我们做练习的时候都会遇到各种各样的错语和异常,最初当不知道程序哪里出错的情况下不可否 ...

  2. python编程快速上手之第8章实践项目参考答案

    第8章实践项目之疯狂填词 创建一个一个疯狂填词(Mad Libs),程序,它将读入文本文件,并让用户在该文本文件中出现 ADJECTIVE,NOUN,VERB等单词的地方,加上他们自己的文本. 首先准 ...

  3. python编程快速上手之第5章实践项目参考答案

    #!/usr/bin/env python3.5 # coding:utf-8 # 5.6.1 # 好玩游戏的物品清单 # 给定一个字典,包含物品名称和数量,并打印出数量对应的物品 dict_stuf ...

  4. python编程快速上手之第3章实践项目参考答案

    1 #!/usr/bin/env python 2 # coding:utf-8 3 # write by mfyang 4 # collatz.py 5 # 从用户读入一个值,并判断这个值是不是一个 ...

  5. python编程快速上手之第7章实践项目参考答案

    #!/usr/bin/env python3.5 #coding:utf-8 import re # 7.18.1 # 强口令检测 # 写一个函数,使用正则表达式,确保传入的口令字符串是强口令 # 长 ...

  6. python编程快速上手之第6章实践项目参考答案

    #!/usr/bin/env python3.5 2 #coding:utf-8 3 # 4 # 这个项目主要目的是字符串的处理,简单格式化输出 5 tableData = [['apples','o ...

  7. python编程快速上手之第4章实践项目参考答案

    #!/usr/bin/env python3.5 # coding:utf-8 # 假定有一个列表,编写函数以一个列表值作为参数,返回一个字条串 # 该字符串包含所有表项,之间以逗号和空格分隔,并在最 ...

  8. Python 编程快速上手 第十四章 处理 CSV 文件和 JSON 数据

    前言 这一章分为两个部分,处理 CSV 格式的数据和处理 JSON 格式个数据. 处理 CSV 理解 csv csv 的每一行代表了电子表格中的每一行,每个逗号分开两个单元格csv 的内容全部为文本, ...

  9. Python 编程快速上手 第十五章 保持时间,计划任务和启动程序

    前言 这一章节的主要内容是: 处理时间类型的数据(使用python 的两个模块: time 和 datetime 来处理) 创建多个线程 (使用 threading 模块来创建多个线程) 进行多个进程 ...

随机推荐

  1. Windows、Office系列产品精华部分集锦

    提示 有了这个帖子麻麻再也不用担心我因为四处找Microsoft家的软件和系统而四处劳累所烦恼了! 首先,你们最爱的老XP同志,XP同志虽然退休了,但是依然坚持在岗位上,向他致敬!! Windows ...

  2. VR全景智慧城市:VR全景技术分析与研究

    全景智慧城市,多年从事三维全景技术应用的互联网公司,我们利用计算机图形学.多媒体.人工智能和计算机网络技术,深入研发和推广虚拟现实9VR0技术的行业应用.如官方网站升级+720度全景.微网站建设+72 ...

  3. # Instrument Time Profiler教程之Time Profiler

    Instrument Time Profiler教程之Time Profiler 一. 介绍 Time Profiler帮助我们分析代码的执行时间,找出导致程序变慢的原因,告诉我们"时间都去 ...

  4. jQuery插件 -- 图片随页面滚动fixed

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. MySql的学习笔记

    良好的理解sql语句: 列:理解可以运算的成变量 where: 理解成表达式,放在行中看是否成立 查出来的结果可以当成一张表理解,select 套用select综合查询:   五种查询 where g ...

  6. 关于Atlassian无法注册的问题,请看过来

    好多童鞋在用团队构建工具git的时候,必然用到git的可视化工具sourceTree来管理项目一些操作,那么当我们下载完sourTree的时候,会有一个选择,已有账户登录还是免费账户,免费账户只有三十 ...

  7. jsonp跨域再谈

    昨天面试雷锋网,问到了jsonp跨域的问题,其实这个问题之前就会的,没有多大的深入,记得有一个名词在跨域中出现,就是同源机制, JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在J ...

  8. javascript走马灯的效果(文档标题文字滚动)

    做一些网站的时候,文档标题会滚动,这个效果是走马灯的效果. <!DOCTYPE html> <html> <head> <meta charset=" ...

  9. 关于php网络爬虫phpspider。

    前几天,被老板拉去说要我去抓取大众点评某家店的数据,当然被我义正言辞的拒绝了,理由是我不会...但我的反抗并没有什么卵用,所以还是乖乖去查资料,因为我是从事php工作的,首先找的就是php的网络爬虫源 ...

  10. 深入理解 JavaScript 事件循环(一)— event loop

    引言 相信所有学过 JavaScript 都知道它是一门单线程的语言,这也就意味着 JS 无法进行多线程编程,但是 JS 当中却有着无处不在的异步概念 .在初期许多人会把异步理解成类似多线程的编程模式 ...