系统运维人员会执行一些如处理不同文件、目录和数据的任务。本章中,我们将学习os模块。os模块提供了与操作系统进行交互的功能。Python编程人员可轻易地使用os模块来执行文件和目录操作。os模块为程序员提供了处理文件、路径、目录和数据的工具。
本章中我们将学习如下内容:
- 使用os模块来处理目录
- 复制、移动、重命名和删除数据
- 处理路径、目录和文件
- 对比数据
- 合并数据
- 模式匹配文件和目录
- 元数据:数据的数据
- 压缩和还原
- 使用tarfile模块来创建TAR存档
- 使用tarfile模块来检查TAR文件内容
目录或文件夹是一个文件和子目录的集合。os模块提供了允许我们与操作系统交互的不同函数。这一部分中,我们将学习可在处理目录时使用的一些函数。
要开始对目录进行处理,首先我们会获取当前工作目录的名称。os有一个getcwd()函数,使用它我们可以获取到当前的工作目录。启动python3终端并输入如下命令来获取当前目录名:
$ python3
Python 3.5.2 (default, Nov 12 2018, 13:43:14)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getcwd()
'/home/student/Chapter05'
>>>
使用os模块,我们可以更换当前工作目录。os模块中有一个chdir()函数可用于实现,示例如下:
>>> os.chdir('/home/student')
>>> print(os.getcwd())
/home/student
>>>
列出目录内容在Python中也很容易。我们将使用os中带有的listdir()函数,它会返回当前工作目录的文件和目录名:
>>> os.chdir('/home/student')
>>> os.listdir()
['Chapter05', 'Chapter03', '.python_history', '__pycache__', 'Chapter01', 'Desktop', 'Chapter04', 'Chapter02', '.cache', '.local', '.ssh', '.bash_history', '.bash_lo
Python中的os模块有一个rename()函数,可帮助更换目录的名称:
>>> os.mkdir('work')
>>> os.rename('work', 'work1')
>>> os.listdir()
['Chapter05', 'Chapter03', '.python_history', '__pycache__', 'Chapter01', 'Desktop', 'Chapter04', 'Chapter02', '.cache', 'work1', '.local', '.ssh', '.bash_history', '.bash_logout', '.bashrc', '.viminfo', '.profile']
我们将学习系统运维人员处理数据的四个基本操作,即复制、移动、重命名和删除。Python内置一个名为shutil的模块,用于执行这些任务。使用shutil模块,我们也可以对数据执行更高级别的操作。在我们的程序中使用shutil模块,只需要编写import shutil导入语句即可。shutil模块提供了一些支持文件复制和删除操作的函数。我们来逐一学习这些操作。
这一部分中,我们将来看如何使用shutil模块来复制文件。首先,我们会创建一个hello.py文件并在其它编写一些文本内容。
# hello.py
print("")
print("Hello World\n")
print("Hello Python\n")
现在我们会在shutil_copy_example.py脚本中编写复制的代码。在其中编写如下内容:
import shutil
import os
shutil.copy('hello.py', 'welcome.py')
print('Copy Successful')
运行脚本如下:
$ python shutil_copy_example.py
# 输出结果
Copy Successful
查看welcome.py脚本,我们会发现welcome.py中已成功地拷贝了hello.py中的内容。
这里我们来看如何剪切数据。实现剪切我们可以使用shutil.move()。shutil.move(source, destination可以将文件从源地址移动到目的地址。下面我们来创建一个shutil_move_example.py脚本并编写如下内容:
import shutil
shutil.move('/home/student/sample.txt', '/home/student/Desktop/.')
运行脚本如下:
$ python3 shutil_move_example.py
这一脚本中,我们剪切的文件为sample.txt,在/home/student 目录中。/home/student是我们的源文件夹/home/student/Desktop是我们目的文件夹。因此,在运行脚本后,sample.txt会从/home/student剪切到/home/student/Desktop目录中。
在前面的部分中,我们学习了如何使用shutil.move()来将文件由源目录移动到目标目录。使用shutil.move()可对文件进行重命名。创建一个shutil_rename_example.py脚本并添加如下内容:
import shutil
shutil.move('hello.py', 'hello_renamed.py')
运行脚本如下:
$ python3 shutil_rename_example.py
# 无输出
现在查看文件名,会被重命名为hello_renamed.py。
我们将学习如何使用Python中的os模块删除文件和文件夹。os模块中的remove()方法将删除文件。如果尝试使用该方法删除目录将会返回OSError。要删除目录,使用rmdir()。
下面创建一个os_remove_file_directory.py脚本并编写如下内容:
import os
os.chdir('/home/student') # 补充代码
os.remove('sample.txt')
print("File removed successfully")
os.rmdir('work1')
print("Directory removed successfully")
运行脚本如下:
$ python3 os_remove_file_directory.py
# 输出结果:
File removed successfully
Directory removed successfully
下面我们将学习os.path()。它用于路径处理。这一部分中,我们来看os模块中针对路径名的函数。
补充: Alan 对 Python 进行了一下升级,方法如下:
sudo apt-get update
sudo wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
tar zxvf Python-3.7.2.tgz
cd Python-3.7.2/
./configure
make && sudo make install
启动python3终端:
$ python3
Python 3.7.2 (default, Feb 26 2019, 15:56:02)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>>
- os.path.absname(path): 返回路径名的绝对路径
>>> os.path.abspath('sample.txt')
'/home/student/work/sample.txt'
>>>
- os.path.dirname(path): 返回路径的目录名
>>> os.path.dirname('/home/student/work/sample.txt')
'/home/student/work'
- os.path.basename(path): 返回路径的基本名称
>>> os.path.basename('/home/student/work/sample.txt')
'sample.txt'
- os.path.exists(path): 如果引用的路径存在则返回 True
>>> os.path.exists('/home/student/work/sample.txt')
True
- os.path.getsize(path): 以字节数返回输入文件的大小
>>> os.path.getsize('/home/student/work/sample.txt')
39
- os.path.isfile(path): 检查输入的路径是否为已有文件。如果是文件则返回True。
>>> os.path.isfile('/home/student/work/sample.txt')
True
- os.path.isdir(path): 检查输入的路径是否为已有目录。如果是目录则返回True。
>>> os.path.isdir('/home/student/work/sample.txt')
False
下面我们将学习如何在Python中比较数据。我们使用pandas模块来进行实现。
pandas是一个开源的数据分析库,提供易于使用的数据结构和数据分析工具。让我们导入和分析数据更为简单。
在开始示例之前,确保系统中安装了pandas。安装pandas的方法如下:
pip3 install pandas # Python3
或
pip install pandas #python2
我们将学习一个使用pandas比较数据的示例。首先,我们来创建两个csv文件:student1.csv和student2.csv。我们将比较这两个csv文件并在结果中返回比较结果。创建以下两个csv文件:
创建student1.csv文件内容如下:
Id,Name,Gender,Age,Address
101,John,Male,20,New York
102,Mary,Female,18,London
103,Aditya,Male,22,Mumbai
104,Leo,Male,22,Chicago
105,Sam,Male,21,Paris
106,Tina,Female,23,Sydney
创建student2.csv文件内容如下:
Id,Name,Gender,Age,Address
101,John,Male,21,New York
102,Mary,Female,20,London
103,Aditya,Male,22,Mumbai
104,Leo,Male,23,Chicago
105,Sam,Male,21,Paris
106,Tina,Female,23,Sydney
下面我们创建compare_data.py脚本并编写如下内容:
import pandas as pd
df1 = pd.read_csv('student1.csv')
df2 = pd.read_csv('student2.csv')
s1 = set([tuple(values) for values in df1.values.tolist()])
s2 = set([tuple(values) for values in df2.values.tolist()])
s1.symmetric_difference(s2)
print(pd.DataFrame(list(s1.difference(s2))), '\n')
print(pd.DataFrame(list(s2.difference(s1))), '\n')
运行脚本如下:
$ python3 compare_data.py
# 输出结果:
0 1 2 3 4
0 104 Leo Male 22 Chicago
1 101 John Male 20 New York
2 102 Mary Female 18 London
0 1 2 3 4
0 102 Mary Female 20 London
1 104 Leo Male 23 Chicago
2 101 John Male 21 New York
在上述的例子中,我们比较两个csv文件的数据:student1.csv和student2.csv。我们首先转化我们的数据帧(df1, df2)为集合 (s1, s2)。然后我们使用了symmetric_difference() 集合。因此它会检查s1和s2的对称性区别,然后我们打印出了结果。
我们将学习如何在Python合并数据。为此,我们使用Python中的pandas库。要进行数据合并,我们将使用前一部分中使用的两个csv文件:student1.csv和student2.csv。
下面,创建merge_data.py脚本并编写如下代码:
import pandas as pd
df1 = pd.read_csv('student1.csv')
df2 = pd.read_csv('student2.csv')
result = pd.concat([df1, df2])
print(result)
运行脚本如下:
$ python3 merge_data.py
# 输出结果:
Id Name Gender Age Address
0 101 John Male 20 New York
1 102 Mary Female 18 London
2 103 Aditya Male 22 Mumbai
3 104 Leo Male 22 Chicago
4 105 Sam Male 21 Paris
5 106 Tina Female 23 Sydney
0 101 John Male 21 New York
1 102 Mary Female 20 London
2 103 Aditya Male 22 Mumbai
3 104 Leo Male 23 Chicago
4 105 Sam Male 21 Paris
5 106 Tina Female 23 Sydney
这部分中我们将学习文件和目录的模式匹配。Python有一个glob模块,用于查找与指定模式相匹配的文件和目录名称。
下面我们来看一个示例。首先,创建一个pattern_match.py脚本并编写如下内容:
import glob
file_match = glob.glob('*.txt')
print(file_match)
file_match = glob.glob('[0-9].txt')
print(file_match)
file_match = glob.glob('**/*.txt', recursive=True)
print(file_match)
file_match = glob.glob('**/', recursive=True)
print(file_match)
运行脚本如下:
$ python3 pattern_match.py
# 输出结果
['file1.txt', 'filea.txt', 'fileb.txt', 'file2.txt', '2.txt', '1.txt', 'file.txt']
['2.txt', '1.txt']
['file1.txt', 'filea.txt', 'fileb.txt', 'file2.txt', '2.txt', '1.txt', 'file.txt', 'dir1/3.txt', 'dir1/4.txt']
['dir1/']
注: 以上目录及文件需自行创建
在前面的示例中,我们使用了Python模块来进行模式匹配。glob (pathname)将返回匹配pathname的名称列表。在我们的脚本中,我们传入了四个不同的glob()函数。第一个glob()中,我们传入的路径名为*.txt,这将返回所有后缀名为.txt文件名。在第二个glob()中,我们传入了 [0-9].txt,这将返回以数字开始的名称。在第三个glob()中,我们传入了**/*.txt,将返回文件名和路径名。它还会返回这些目录的文件名。在第四个glob()中,我们传入了**/,将仅返回目录名。
这部分我们将学习PyPDF2模块,有助于我们从pdf文件中提取元数据(metadata)。但首先什么是元数据呢?元数据是数据的数据。元数据是描述主要信息的结构性信息。它是一个数据的总结。包含我们实际数据相关的基本信息。帮助查找我们数据中的具体实例。
ℹ️确保将需提取信息的pdf文件放在相应目录中
首先安装PyPDF2模块,命令如下:
pip3 install PyPDF2
下面我们来编写脚本metadata_example.py,并查看如何获取元数据信息。我们使用Python来编写脚本:
import PyPDF2
def main():
file_name = 'Haltermanpythonbook.pdf'
pdfFile = PyPDF2.PdfFileReader(open(file_name, 'rb'))
pdf_data = pdfFile.getDocumentInfo()
print('----Metadata of the file----')
for md in pdf_data:
print(md+ ':' +pdf_data[md])
if __name__ == '__main__':
main()
译者注: 1、随机搜索了一本Python 方面的 pdf 图书Haltermanpythonbook.pdf用于本例测试
2、原书使用了 Python 2中的pyPdf,为统一版本,Alan 修改为针对 Python 3的PyPDF2
运行脚本如下:
$ python3 metadata_example.py
----Metadata of the file----
/Author:
/Title:
/Subject:
/Creator:LaTeX with hyperref package
/Producer:pdfeTeX-1.21a
/Keywords:
/CreationDate:D:20111113221308-05'00'
/PTEX.Fullbanner:This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4
在前述脚本中,我们使用了 Pyhon 3中的PyPDF2模块。首先,我们创建了一个变量file_name来存储 pdf 的路径。使用PdfFileReader() 来提取数据。变量pdf_data会存储pdf的相关信息。最后,我们编写for循环来获取元数据信息。
这部分中我们将学习shutil模块中的make_archive()函数,可压缩整个文件夹。为此我们编写一个compress_a_directory.py脚本并编写如下内容:
import shutil
shutil.make_archive('work', 'zip', 'work/')
运行脚本如下:
$ python3 compress_a_directory.py
前述脚本shutil.make_archive()函数中,我们传入的第一个参数作为压缩文件的名称,zip是压缩的技术。work/是想要进行压缩的目录名。
要对压缩文件进行还原(解压缩),我们使用shutil模块中的unpack_archive() 函数。创建一个脚本unzip_a_directory.py并编写如下内容:
import shutil
shutil.unpack_archive('work1.zip')
运行脚本如下:
$ python3 unzip_a_directory.py
现在检查我们的目录。可以得到解压目录后的所有内容。
这部分帮助我们学习如何使用Python的tarfile模块来创建tar存档文件。
tarfile模块用于使用gzip、bz2等压缩技术来读取和写入tar存档文件。确保存在相关的文件和目录。下面创建一个tarfile_example.py脚本并编写如下内容:
import tarfile
tar_file = tarfile.open('work.tar.gz', 'w:gz')
for name in ['welcome.py', 'hello.py', 'hello.txt', 'sample.txt', 'sample1.txt']:
tar_file.add(name)
tar_file.close()
运行脚本如下:
$ python3 tarfile_example.py
这时检查当前工作目录,可以看到已创建了work.tar.gz。
这部分中我们将学习如何在不提取tar文件的情况下检查tar包里的内容。我们使用Python中的tarfile模块。
创建脚本examine_tar_file_content.py编写如下内容:
import tarfile
tar_file = tarfile.open('work.tar.gz', 'r:gz')
print(tar_file.getnames())
运行脚本如下:
$ python3 examine_tar_file_content.py
# 输出结果:
['welcome.py', 'hello.py', 'hello.txt', 'sample.txt', 'sample1.txt']
在前面的例子中,我们使用了tarfile模块来查看所创建的tar文件的内容。我们使用了getnames()函数来读取数据。
本章中我们学习了如何使用Python脚本来处理文件和目录。还学习了如何使用os模块来处理目录。以及如何拷贝、移动、重命名和删除文件和目录。我们学习了Python中的pandas模块,用于比较和合并数据。同时学习了使用tarfile模块来创建tar文件以及读取tar文件中的内容。我们在搜索文件和目录时还使用了模式匹配。
下一章中,我们将学习tar包和ZIP的创建。
☞☞☞ 第六章 文件存档、加密和解密
- 如何在不论什么操作系统中(Windows, Linux)处理不同的路径?
- Python 中print()可以使用哪些不同参数?
- Python 中dir()关键字的用处是什么?
- pandas中的数据帧、序列是什么?
- 列表推导式是什么?
- 是否可以进行集合推导式和字典推导式?如果是如何做?
- 如何使用pandas数据帧打印最前/后的 N 行?
- 使用列表推导式来编写程序打印奇数?
- sys.argv的类型是什么? a) 集合 b) 列表 c) 元组 d) 字符串