本章介介绍了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. 007---Hibernate基本映射标签和属性介绍

    一.映射文件的基本结构举例: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-// ...

  2. Struts2入门(一)

    今天学习Struts2首先struts是一个成熟的框架.Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Cont ...

  3. Linux常用命令-jdk和Tomcat

    一.JDK的安装和配置 1.下载jdk文件 去官方网站下载Linux 64位  jdk-8u131-linux-x64.tar.gz 2.使用Ftp工具上传到/usr/local 下. 使用命令:ta ...

  4. 在Quo.js下Tap和singleTap的区别

    前两天上网搜开发手机页面的JS,看到了Quo.js下载下来后来看了一下,支持的触屏手势挺多的,在一般的开发中应该够用了,更让我喜欢它的一点是它跟JQ差不多(虽然功能不如JQ强大但是语法基本一致).这就 ...

  5. javascript常用开发笔记:一个简单强大的js日期格式化方法

    前言:一直没找到好用的javascript日期格式化工具,自己写了一个,方便以后复用 1.主要功能 (1)支持任意顺序的日期格式排列:yyyy=年,MM=月,dd=日,HH=时,mm=分,ss=秒,s ...

  6. cocoapod升级

    1.0 重新安装问题 cd /user/xx/.cocoapod/repos rm -rf master pod setup /user/xx/.cocoapod/repos 查看目录文件夹大小: d ...

  7. Mybatis中javaType和jdbcType对应和CRUD例子

    JDBC Type Java Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIM ...

  8. idea live template高级知识, 进阶(给方法,类,js方法添加注释)(二)

    上一篇文章(http://www.cnblogs.com/xzjxylophone/p/6994488.html) 是在 groovyScript中直接添加的代码,这个看起来是简单,粗暴,麻烦和不美观 ...

  9. ecshop邮件订阅按“订阅”没反应

    原订阅邮件所使用的JS文件transport.js和JQuery冲突,会更改transport.js文件,用以下代码可同样实现订阅功能. <input type="text" ...

  10. js中的confirm的运用

    <a href="javascript:void(0);" onclick='tuichu_queren();'>安全退出</a> <script t ...