本章介介绍了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. 最简单 iText 的 PDF 生成方案(含中文解决方案)HTML 转为 PDF

    转自:http://my.oschina.net/sanji/blog/277704 最近正好项目有用到 ITEXT ,在网络上搜索了一番,发现了很多方案,但是感觉对于一般开发来说都太复杂了,本文提供 ...

  2. Unity应用架构设计(10)————绕不开的协程和多线程(Part 1)

    在进入本章主题之前,我们必须要了解客户端应用程序都是单线程模型,即只有一个主线程(Main Thread),或者叫做UI线程,即所有的UI控件的创建和操作都是在主线程上完成的.而服务器端应用程序,也就 ...

  3. 对RabbitMQ.Client进行一下小小的包装,绝对实用方便

    RabbitMQ是一个老牌的非微软的消息队列组件,一般来说应该能满足中小型公司对消息队列生产的需求,平时我们在.NET开发环境下运用它是可能会需要RabbitMQ.Client的SDK库,此库是官网提 ...

  4. Best packages for data manipulation in R

    dplyr and data.table are amazing packages that make data manipulation in R fun. Both packages have t ...

  5. Web开发安全小贴士

    想要开发出一个安全的.健壮的Web应用其实是非常困难的, 如果你想要快速开发出一款集使用价值.用户体验度.以及安全性为一身的产品,以下安全步骤很必要!!!     数据库 1.对类似访问令牌.电子邮箱 ...

  6. phpcms插件

    最近在研究PHP,学了一段时间后感觉想自己写点东西,但是又不知道写什么,最后把目标对准了PHPCMS的插件,从网上找了一下,大部分教程都只是教怎么写插件的具体代码,而没有教怎么把插件打成安装包,特别是 ...

  7. 修改cms版权等等信息

    目的:为DedeCMS换上精美多样的提示信息窗口 用到的开源项目:DedeCMS,artdialog 步骤: 1.下载include.rar文件完成后,解压得到2个php文件和一个使用说明文件,将ph ...

  8. 使用OTP动态口令(每分钟变一次)进行登录认证

    GIT地址:https://github.com/suyin58/otp-demo 在对外网开放的后台管理系统中,使用静态口令进行身份验证可能会存在如下问题: (1) 为了便于记忆,用户多选择有特征作 ...

  9. js基础回顾-数据类型和typeof怎么用

    js的基本数据类型有六种,undefined.null.number.string.boolean.object. 未定义        空      数字        字符串    布尔     ...

  10. PyQt5环境搭建及cx_freeze打包exe

    Python的图形库也有好几个,Qt文档和使用面还是要广一些. 打包成可执行文件的也有好几个,PyInstaller用的比较多,但是PyInstaller目前还不支持Python3.6(开发版支持3. ...