本章介介绍了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. MacBook使用之配置jdk&Eclipse

    查看系统版本:关于本机-软件-查看当前版本信息 打开另一个Finder的快捷键:Command + n 终端命令:Finder - 使用工具 - 终端命令 配置jdk系统变量: cd ~ touch ...

  2. BattleInfo

    private Dictionary<string, UILabel> mLabels; private Dictionary<string,UISprite> mSprite ...

  3. Tomcat 安装与配置

    1. 将压缩文件“apache-tomcat-7.0.62.zip ”上传到linux系统目录:/home/下 2. 进入目录 cd /home/ 解压文件,执行如下命令:unzip apache-t ...

  4. python3 爬 妹子图

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式 Beautiful Soup 4 通过PyP ...

  5. Java的必备开发工具

    身为一个Java开发的爱好者,你不得不承认需要安装以下软件 NO.1 Java开发工具包 Java JDK 可以说这个工具包不得不安装,因为这个工具包是开发Java程序的核心! Java JDK工具包 ...

  6. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  7. Java IO流之【缓冲流和文件流复制文件对比】

    与文件流相比,缓冲流复制文件更快 代码: package Homework; import java.io.BufferedOutputStream; import java.io.File; imp ...

  8. android 定时器(Handler Timer Thread AlarmManager CountDownTimer)

    Android实现定时任务一般会使用以上(Handler Timer Thread AlarmManager CountDownTimer)五种方式.当然还有很多组合使用(比如Handler+Thre ...

  9. java源码学习(四)ArrayList

    ArrayList ​ ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ​ ArrayList不是线程安全的,只能用在单线程环境下, ...

  10. watchdog(IWDG)

    1.为了避免程序忙跑跑死了没反应,加上一个看门狗watchdog实时监控着程序,一旦程序没有在规定的时间喂狗,则狗叫使得单片机复位. 2.Independent watchdog(IWDG)内部有时钟 ...