基础搜索方法:

用 pathlib 库搜索文件用 Python 搜索文件时需要使用 pathlib 库的 glob() 函数和 rglob() 函数,glob() 函数可以实现基于文件名的搜索方法,rglob 函数可以实现基于扩展名的搜索方法。


from pathlib import Pathbase_dir = '/Users/edz/Desktop/'
keywords = '**/*BBC*'# 遍历base_dir指向的目录下所有的文件
p = Path(base_dir)# 当前目录下包含BBC的所有文件名称
files = p.glob(keywords)
# files的类型是迭代器
# 通过list()函数转换为列表输出
# print(list(files))# xlsx结尾的文件
files2 = p.rglob('*.xlsx')
print(list(files2))# 遍历子目录和所有文件
files3 = p.glob('**/*')
print(list(files3))

由于 glob() 进行匹配的是文件的路径和文件名称方式,如: “c:\somepath\to\filename_include_BBC_voice.exe” , 而我们进行文件搜索的时候一般会使用关键字,如“BBC”,因此在搜索时我们需要为关键字加上通配符的形式,如“BBC” 。

通配符是类似正则表达式的元字符的一种特殊符号,它不能用在正则表达式中,只能用在 glob(全称 global)匹配模式中。

rglob 函数是从文件路径末尾向前进行匹配的,这是它和 glob() 函数的主要区别, 基于 rglob() 函数的搜索顺序特点,经常被我们用于进行扩展名的搜索,比如说采用 rglob(’*.xlsx’) 就可以搜索所有的 xlsx 扩展名文件,要比使用 glob() 编写的模式匹配更简单,参数的含义也更清晰。

最后再看一下 glob() 和 rglob() 函数的返回值,有一点我需要提醒你:它们的执行结果是我们之前课程中没有接触过的一种新的数据类型,这种类型叫做“迭代器”。

提升搜索效率的两种方法

用 Python 的 pathlib 库实现文件搜索,只是在灵活性上比 Windows 默认的搜索更好,但是搜索效率上并不能带来任何提高。为了减少搜索的等待时间, 接下来,我就教你使用指定搜索路径和建立索引文件两个方法, 提高 pathlib 库的搜索效率。

指定搜索路径

我们先来看第一种,指定搜索路径。
我们需要通过三个步骤实现:

先生成配置文件,把要搜索的路径写入到配置文件中;

再编写读取配置文件和搜索的自定义函数,把配置文件中的路径读取出来,逐个目录搜索;

最后,将多个目录的搜索结果合并输出,便于你通过结果快速找到自己想要的文件。

先说第一步,怎么使用 Python 读取配置文件。以往我们会把要搜索的路径写入到变量,并把定义路径的变量名称放在代码前几行的位置,便于下次修改搜索目录的时候找到这个变量。但是对于代码工程稍微复杂的程序来说,往往会有多个代码文件,仍然不利于每次搜索的时候进行搜索路径的修改。新的方法,就是把变量放入到一个单独的文件中,这个文件被称作该代码的配置文件。

这种方法的好处是你修改搜索目录时不用打开代码文件。假设你的朋友也需要类似功能,那你就可以把代码和配置文件一起发给他,哪怕他完全不会 Python,也能使用你编写的程序实现高效搜索。

配置文件一般为文本文件。配置文件的格式,一般由软件作者基于软件的功能和自己的习惯来指定,不过也有通用的配置文件格式。

比如在 Windows 系统中,最常见的配置文件是扩展名为.ini 的文件,在今天这节课,我们就把.ini 文件格式作为配置文件的标准格式。.ini 文件格式包含三个部分,分别是节、参数和注释。格式如下:


节
[section]
参数
(键=值)name=value
注释
注释使用“;”分号表示。在分号后面的文字,直到该行结尾都全部为注解。
;注释内容
#基于.ini 文件的格式,我把配置搜索路径的配置文件修改为如下:
[work]
;工作文件保存路径
searchpath=/Users/edz,/tmp[game]
;娱乐文件保存路径
searchpath=/games,/movies,/music

在这段代码中,我设置了 work 和 game 两个“节”,分别代表工作和娱乐。这样设置的好处是,我可以根据不同的用途来搜索不同的目录。如果搜索时使用了更少的目录,也会相应减少搜索的等待时间。

另外,你会发现两个“节”中的参数我都指定成相同的名字 --searchpath,这样设置的好处是我将搜索范围从“工作”改为“娱乐”时,只需要在代码里修改搜索的“节”,不用修改搜索的参数。

除了“节”和“参数”,在配置文件中,你还应该关注我对参数 searchpath 设置值的方式,它的值是我想要进行搜索的路径范围,为了在程序中能够更方便得读取多个路径,我使用逗号来分隔多个路径。

找到 search.ini 文件完整路径之后,接下来需要读取并分析.ini 文件格式,Python 有实现这个功能的的库,它叫做 configparser 库,通过这个库你可以直接读取.ini 文件中的 searchpath 参数,不用通过 read() 函数读取文件内容,手动编写分析.ini 文件的脚本了。


import configparser
import pathlib
from pathlib import Pathdef read_dirs(ini_filename, section, arg):"""通过ini文件名,节和参数取得要操作的多个目录"""current_path = pathlib.PurePath(__file__).parentinifile = current_path.joinpath(ini_filename)# cf是类ConfigParser的实例cf = configparser.ConfigParser()# 读取.ini文件cf.read(inifile)# 读取work节 和 searchpath参数 return cf.get(section, arg).split(",")def locate_file(base_dir, keywords):p = Path(base_dir)files = p.glob(keywords) return list(files)dirs = read_dirs('search.ini', 'work', 'searchpath')
# ['/Users/edz', '/tmp']
keywords = '**/*BBC*'# 定义存放查找结果的列表
result = []# 从每个文件夹中搜索文件
for dir in dirs:files = locate_file(dir, keywords)result += files# 将PosixPath转为字符串
print( [str(r) for r in result] )

read_dirs() 函数实现了读取.ini 文件,并将返回的多个路径处理为列表类型。列表类型适合多组并列的数据,多个目录刚好可以使用列表这种数据类型来存放要搜索的目录名称。

locate_file() 函数通过代码的第 35 行循环功能,对每个目录进行了搜索,并将搜索的结果存入 result 变量。result 变量是一个列表数据类型,由于搜索到的文件可能包含多个匹配的文件路径,我需要将搜索到的结果依次存入 result 列表中,再继续搜索下一个目录,继续通过 append() 函数将结果放入列表,直到所有的目录搜索完成,整个搜索的程序才真正执行结束。

最后还有一点需要你注意,在进行路径处理的过程中,pathlib 库为了规避不同操作系统路径写法的差异,就把路径统一定义为 PosixPath() 对象。因此,你在使用这些路径的时候,需要先将 PosixPath 对象转换为字符串类型。我在代码最后一行通过 Python 内置函数 str() 函数把 PosixPath 对象逐个转换为字符串类型,并再次存入到列表当中。

建立索引文件

我们可以基于指定搜索路径的程序进行改造:先把配置文件目录下所有文件路径的保存方式由列表改为文件;再把搜索功能改为从文件搜索。


def locate_file(base_dir, keywords='**/*'):"""迭代目录下所有文件"""p = Path(base_dir)return p.glob(keywords)def write_to_db():"""写入索引文件"""current_path = pathlib.PurePath(__file__).parentdbfile = current_path.joinpath("search.db")with open(dbfile, 'w', encoding='utf-8') as f:for r in result:f.write(f"{str(r)}\n")# 读取配置文件
dirs = read_dirs('search.ini', 'work', 'searchpath')# 遍历目录
result = []
for dir in dirs:for files in locate_file(dir):result.append(files)# 将目录写入索引文件
write_to_db()

在代码中我增加了 write_to_db() 函数,它在代码的第 16-18 行,我通过写入文件方式替代了写入列表的功能。同时,为了能遍历所有的目录,我还修改了 locate_file() 函数的第二个参数,将它改为“keywords='/*'”。通过这两处的修改,就把所有文件路径全部保存到 search.db 文件中了。**

search.db 的文件内容如下,这里记录了配置文件指定的所有目录下的所有文件路径:


/tmp/com.apple.launchd.kZENgZTtVz
/tmp/com.google.Keystone
/tmp/mysql.sock
/tmp/com.adobe.AdobeIPCBroker.ctrl-edz
/tmp/com.apple.launchd.kZENgZTtVz/Listeners
/tmp/com.google.Keystone/.keystone_install_lock
... ...

从文本中搜索关键字


import pathlib
import rekeyword = "apple"# 获取索引文件路径
current_path = pathlib.PurePath(__file__).parent
dbfile = current_path.joinpath("search.db")# 在索引文件中搜索关键字
with open(dbfile, encoding='utf-8') as f:for line in f.readlines():if re.search(keyword, line):print(line.rstrip())

在代码中我利用正则表达式的 re.search() 搜索函数,以 keyword 变量作为搜索的关键字,对 search.db 索引文件的每一行进行了匹配,最后将符合关键字“apple”的文件路径和名称一起显示在屏幕上。

使用这种方式来搜索文件,要比使用操作系统自带的搜索工具快得多,因为我将原本 Windows 搜索硬盘上的文件所消耗的时间拆分成了两部分。一部分是 updatedb.py 建立索引的时间;一部分是从 search.db 索引文件查找关键字的时间。

使用Python进行文件快速搜索(建立文件搜索索引)相关推荐

  1. 记录----如何将FLV格式文件快速转换为mp4文件

    如何将FLV格式文件快速转换为mp4文件 今天用硕鼠下载视频的时候发现下载出来的视频是.flv格式的,没有相应的播放器无法播放,于是找了个方法把它转换为MP4文件,记录一下 第一步 下载一个辅助工具, ...

  2. Python删除文件夹和建立文件夹

    import os import shutilif os.path.isdir(dir): #判断文件夹dir是否存在shutil.rmtree(dir, True) #删除文件夹dir os.mkd ...

  3. ftp服务器怎么添加文件夹,批量建立文件夹,为Serv_U批量创建用户

    批量建立文件夹,为Serv_U批量创建用户 更新时间:2011年04月03日 00:50:27   作者: 最近要用serv u为用户开ftp服务器,而且一个目录对应一个账号,账号很多,一个一个的建立 ...

  4. 一键创建多个文件夹?快速批量建立文件夹并命名?

      遇到要创建多个文件夹,少的可以用这个方法:要几个就V 1几个,然后再 F2 重命名.可行!但一多那-咱就不说效不效率,就一个个的F2也烦啊!能同时创建,它不香嘛! 方法 / 步骤目录:   遇到要 ...

  5. Python小技巧——快速给大量文件命名

    当做爬虫项目的时候,有时需要爬取大量的图片到本地,既然是保存到本地了,就得给图片一个名字对吧,有的网站没有给图片命名,所以我们需要在保存到本地时自己给图片命名,但是图片的数量非常多,怎么操作才能给每张 ...

  6. linux 下根据cpp文件快速书写头文件

    假设我们现在有一个hello.cc文件,我们如果想要书写它的头文件hello.h,使用如下的命令即可: cat hello.cc | grep "^\w.*)$" > hel ...

  7. mysql innodb表移植_mysql Innodb引擎独立表空间下通过复制.ibd文件快速迁移数据文件...

    假设需求:需要把库test1中的的数据迁移到test2中,并且test2中数据量特别大 硬性条件:1.mysql 使用 Innodb引擎,且开启独立表空间,2.两个库的mysql版本一致(不同版本下未 ...

  8. 【利用Arcpy快速检索矢量文件和栅格文件并进行统计和删除工作】

    这里写目录标题 场景分析 解决思路和方法 解决思路 代码 拓展的知识及应用分析 快速获取文件夹中的所有矢量文件和栅格文件名称 矢量文件 栅格文件 快速数据库中的矢量文件和栅格文件名称 快速读取每个矢量 ...

  9. 用MATLAB快速修改txt文件

    用MATLAB快速修改txt文件 快速修改txt文件 概要: 做数据集或使用别人的数据集的时候一般会有一个txt格式的文件,其内容是所有带路径的文件名.此时可能因为路径等原因需要需要对这个txt文件进 ...

  10. mysql导入sas文件夹_SAS建立本地文件夹

    SAS建立本地文件夹 SAS建立文件夹:用sas建立数据集市时,通常要生成每日数据并保留起来. 今天分享一段程序,SAS生成每日文件夹.模块文件夹及主题表文件夹并保留每日运行的日志,在下一期,分享日志 ...

最新文章

  1. 深度 | 香港中文大学(深圳)张大鹏教授:生物特征识别的新进展 | CCF-GAIR 2019
  2. pythonweb开发-Web | 浅谈用Python进行Web开发
  3. 【五校联考7day1】n染色
  4. web前端技术分享:使用react实现简易路由
  5. android动态切换logo和label
  6. python及拓展版_python扩展模块
  7. Mqtt客户端与服务端通讯
  8. 网络攻防WEB入门指南
  9. flash在线拍照并上传
  10. [转贴][教学] 教你如何打飞机 ^_^
  11. kafka单条消息太大引起的线上故障
  12. 解决Windows10关闭UAC后,开机启动项不生效的问题
  13. HDU5956 The Elder(树上斜率DP)
  14. 超低频测试信号产生电路软件流程图,超低频任意波形信号发生器方案设计书.doc...
  15. 苹果手机可以投影到墙上吗_怎么将手机上的投影到电视上或墙上?
  16. Android主线程耗时方法监控
  17. Eolink 征文活动- -后端研发需要的API文档工具
  18. uni-app相机组件实现自定义二维码扫描
  19. 如何选择我的搜索引擎关键字?
  20. openlayers3教程详细_OpenLayers 3 入门教程

热门文章

  1. 分析内网即时通讯软件安全性如何
  2. xml文件转json文件
  3. 【电信学】【2019.07】基于ATOLL的5G网络规划与优化
  4. 14、CSS渲染:CSS是如何绘制颜色的?
  5. Laravel 数据库迁移
  6. 刘帅嵌入式系统-MLA指令
  7. 【整数规划算法】分支定界法及其Python代码实现
  8. jwplayer android m3u8,播放上jwplayer M3U8文件,而RTMP
  9. ant design——Modal
  10. 移动前端开发的一些简单分类!