## 源代码运行,需要先安装第三方模块
## Excel 格式,需要先安装模块,安装命令 pip install xlrd
## Word docx 格式,需要先安装模块,安装命令 pip install python-docx
## Word doc 格式,需要先安装模块,安装命令 pip install pypiwin32
## pdf 格式,需要先安装模块,python3安装命令 pip install pdfminer3k
## pptx 格式,需要先安装模块,安装命令 pip install python-pptx
## 打包成exe格式运行
## 先安装第三方依赖模块
## 再安装打包工具
pip install PyInstaller -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
【注意】
源代码开头要有字符集
源代码文件名只能有ASCII字符集内字符
# -*- coding: UTF8 -*-
## 打开CMD
cd 到源代码所在目录
## 如果是GUI图形界面程序,可以加 -w 去掉黑框后台显示
pyinstaller -w -F 源代码.py
-F 表示生成单个可执行文件
-w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!
-p 表示你自己自定义需要加载的类路径,一般情况下用不到
-i 表示可执行文件的图标
## 如果一切顺利,在源代码目录中会出现dist文件夹,里面有一个同名exe文件,这个文件可以在别的无python的环境下直接运行(在32位系统上打包的程序可以在32位和64位运行,在64位打包的程序只能在64位环境运行)
# -*- coding: UTF8 -*-
## 递归遍历目录,根据扩展名找出需要的搜索内容的文件生成文件列表,根据扩展名用关键字或者RE正则表达式逐个搜索文件内容
## V 1.0
## V 1.1 增加 pptx 格式
## V 1.2 使用线程,防止搜索大文件时图形界面被卡住
import threading # 多线程
import os
import chardet # 判断文本文件的字符编码 pip install chardet
import re
import csv ## CSV 格式
import zipfile ## ZIP 格式
import xlrd ## Excel 格式,需要先安装模块,安装命令 pip install xlrd
from docx import Document ## Word docx 格式,需要先安装模块,安装命令 pip install python-docx
from win32com import client as wc ## Word doc 格式,需要先安装模块,安装命令 pip install pypiwin32
from pptx import Presentation ## pptx 格式,需要先安装模块,安装命令 pip install python-pptx
## pdf 格式,需要先安装模块,python3安装命令 pip install pdfminer3k
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBox
# 递归遍历目录
def DEF_目录_递归遍历(D):
try:
L = os.listdir(D) # 获取目录里面的内容列表(可能会遇到权限问题)
except Exception as e:
ERROR = f'【错误】读取目录失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
if L != []: # 如果目录不空
for i in L: # 遍历目录里面的内容
FullFileName = D + '\\' + i
if os.path.isdir(D + '\\' + i): # 如果还是目录
DEF_目录_递归遍历(D + '\\' + i) # 循环递归进入目录
else: # 不是目录就是文件
文件名, 扩展名 = os.path.splitext(i) # 分割文件名和扩展名,返回元组,无扩展名扩展名部分为空字符串
if IV_忽略文件扩展名大小写.get() == 1:
扩展名 = 扩展名.lower() # 扩展名转成小写
if 扩展名 in 扩展名集合: ## 全局变量 扩展名集合
文件列表.append((FullFileName, 扩展名)) ## 全局变量 文件列表:保存路径和文件全名扩展名
else:
WARNING = f'【注意】空目录 {D}'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
# 初始化目录
def DIR_init(目录):
DEBUG = f'【调试】初始化 {目录}'
Text_搜索日志文本.insert('end', DEBUG+'\n')
if os.path.isdir(目录): # 判断是否是目录
DEF_目录_递归遍历(目录)
else:
ERROR = f'【错误】非目录 {目录}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
## 根据文件后缀名进行不同的操作
def 根据文件后缀名选择操作(T, 正则表达式):
FullFileName, FileNameExt = T
if FileNameExt.lower() in ['.txt', '.xml', '.json']:
F_TEXT(FullFileName, 正则表达式)
elif FileNameExt.lower() == '.csv':
F_CSV(FullFileName, 正则表达式)
elif FileNameExt.lower() in ['.xlsx', '.xls']:
F_EXCEL(FullFileName, 正则表达式)
elif FileNameExt.lower() == '.docx':
F_DOCX(FullFileName, 正则表达式)
elif FileNameExt.lower() == '.doc':
F_DOC(FullFileName, 正则表达式)
elif FileNameExt.lower() == '.pptx':
F_PPTX(FullFileName, 正则表达式)
elif FileNameExt.lower() == '.pdf':
F_PDF(FullFileName, 正则表达式)
elif FileNameExt.lower() == '':
F_X(FullFileName, 正则表达式)
elif FileNameExt.lower() == '.zip':
F_ZIP(FullFileName, 正则表达式)
else:
WARNING = f'【注意】暂不支持 {FileNameExt}'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
## 搜索文件内文本内容查找含有关键字的那行内容
def DEF_RE(TEXT, 正则表达式, 显示信息):
if IV_忽略搜索关键字大小写.get() == 1:
RE_fi = re.finditer(正则表达式, TEXT, re.I) # 返回迭代器
else:
RE_fi = re.finditer(正则表达式, TEXT) # 返回迭代器
L_re = [i.group() for i in RE_fi]
if L_re != []:
INFO = f'【信息】{显示信息}匹配【{len(L_re)}】次'
Text_搜索结果文本.insert('end', INFO+'\n')
Text_搜索日志文本.insert('end', INFO+'\n')
for i in L_re:
INFO = f'\t{i}'
Text_搜索日志文本.insert('end', INFO+'\n')
## TEXT 文本文件
def F_TEXT(FullFileName, 正则表达式):
try:
f = open(FullFileName, 'rb')
except Exception as e:
ERROR = f'【错误】【TEXT】{FullFileName} 打开失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
DATA = f.read()
f.close()
编码 = chardet.detect(DATA)['encoding']
if 编码 == None:
ERROR = f'【错误】【TEXT】【无编码信息,无法打开】{FullFileName}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
try:
TEXT = DATA.decode(编码)
except Exception as e:
ERROR = f'【错误】【TEXT】{FullFileName} 尝试编码【{编码}】失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
DEF_RE(TEXT, 正则表达式, FullFileName)
## ZIP压缩文件中的 TEXT 文本格式文件
def ZIP_TEXT(DATA_Bytes, 正则表达式, 显示信息):
编码 = chardet.detect(DATA_Bytes)['encoding']
if 编码 == None:
ERROR = f'【错误】【TEXT】【无编码信息,无法打开】{显示信息}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
try:
TEXT = DATA_Bytes.decode(编码)
except Exception as e:
ERROR = f'【错误】【TEXT】{显示信息} 尝试编码【{编码}】失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
DEF_RE(TEXT, 正则表达式, 显示信息)
## CSV 格式
def F_CSV(FullFileName, 正则表达式):
try:
f = open(FullFileName)
X = csv.reader(f)
## 做成一个单元格一行的文件,方便按行匹配,防止跨行匹配(如需跨行匹配,可以使用自定义正则模式匹配)
L = ['\n'.join(i) for i in X]
TEXT = '\n'.join(L)
f.close()
except Exception as e:
ERROR = f'【错误】【CSV】{FullFileName} 打开失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
print("CSV TEXT", TEXT)
DEF_RE(TEXT, 正则表达式, FullFileName)
## Excel 格式
def F_EXCEL(FullFileName, 正则表达式):
try:
E = xlrd.open_workbook(filename=FullFileName) # 打开文件
except Exception as e:
ERROR = f'【错误】【Excel】{FullFileName} 打开失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
for 工作表名 in E.sheet_names(): # 遍历工作表名 ['Sheet1', 'Sheet2']
工作表 = E.sheet_by_name(工作表名)
行数 = 工作表.nrows
L = [] # 以单元格为元素把Excel中一个Sheet做成一个列表
for i in range(0, 行数):
L += 工作表.row_values(i)
L_str = [str(i) for i in L] # Excel单元格值会有非字符串类型,需要转换为字符串类型
TEXT = '\n'.join(L_str) # 一个单元格拼接一个换行符,方便re以行为单位匹配
显示信息 = f'【Excel】{FullFileName}【Sheet】{工作表名}'
DEF_RE(TEXT, 正则表达式, 显示信息)
## Word docx 格式
def F_DOCX(FullFileName, 正则表达式):
try:
doc = Document(FullFileName)
except Exception as e:
ERROR = f'【错误】【docx】{FullFileName} 打开失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
## 按段落拼接Word中的文本内容
TEXT = ''
for para in doc.paragraphs:
TEXT += para.text + '\n'
#print("TEXT", TEXT)
显示信息 = f'【Word】{FullFileName}【文本内容】'
DEF_RE(TEXT, 正则表达式, 显示信息)
## Word中的表格内容,按每个单元格一行拼接成文本
L = []
for 表格 in doc.tables:
for 行 in 表格.rows:
for 列 in 行.cells:
L.append(列.text)
TEXT_TABLE = '\n'.join(L)
#print("TEXT_TABLE", TEXT_TABLE)
显示信息 = f'【Word】{FullFileName}【表格内容】'
DEF_RE(TEXT_TABLE, 正则表达式, 显示信息)
## Word doc 格式
def F_DOC(FullFileName, 正则表达式):
WARNING = '【注意】doc格式需要转换成docx格式,正在转换,请稍后...'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
FullFileName_NEW = FullFileName + '转格式.docx'
if os.path.exists(FullFileName_NEW):
WARNING = f'【取消转换】已经存在文件或目录 {FullFileName_NEW}'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
else:
word = wc.Dispatch("Word.Application")
doc = word.Documents.Open(FullFileName)
doc.SaveAs(FullFileName_NEW, 12) # 12代表docx
doc.Close()
word.Quit()
WARNING = f'【转换完成】另存为新文件 {FullFileName_NEW}'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
F_DOCX(FullFileName_NEW, 正则表达式)
## pptx 格式
def F_PPTX(FullFileName, 正则表达式):
try:
PY_PPTX = Presentation(FullFileName)
except Exception as e:
ERROR = f'【错误】【pptx】{FullFileName} 打开失败 {e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
## 按页拼接ppt中的文本内容
页码 = 0
for slide in PY_PPTX.slides: # 遍历每一张ppt
页码 +=1
PAGE_TEXT = ''
for shape in slide.shapes: # 遍历页面上每一个元素块(文本框、图片等)
if shape.has_text_frame: # 如果元素块内有文字
PAGE_TEXT += '\n' + shape.text_frame.text # 拼接页面全部元素块内文本,以换行符合分格
#print("页码", 页码, "PAGE_TEXT", PAGE_TEXT)
显示信息 = f'【PPTX】{FullFileName}第【{页码}】页'
DEF_RE(PAGE_TEXT, 正则表达式, 显示信息)
## pdf 格式
def F_PDF(FullFileName, 正则表达式):
WARNING = '搜索大PDF文件比较耗时,请耐心等待...'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
fp = open(FullFileName, 'rb') # 以二进制读模式打开PDF文件
praser = PDFParser(fp) # 实例化pdf解析器,从文件流中获取PDF对象
doc = PDFDocument() # 创建一个PDF文档
praser.set_document(doc) # 分析器关联文档对象
doc.set_parser(praser) # 文档对象关联分析器
doc.initialize() # 文档初始化解密,如果没有密码就创建一个空的字符串
# 判断是否可以将PDF文件转换成txt,不行就直接忽略
if not doc.is_extractable:
raise PDFTextExtractionNotAllowed
rsrcmgr = PDFResourceManager() # 创建资源管理器,负责资源调度,有益于资源共享
laparams = LAParams() # 实例化默认参数空间
device = PDFPageAggregator(rsrcmgr, laparams=laparams) # 创建设备
interpreter = PDFPageInterpreter(rsrcmgr, device) # 创建解释器
# 遍历
页码 = 0
for page in doc.get_pages(): # 遍历doc.get_pages()生成器,生成器对应了PDF每一页的数据源与解析器等配置
页码 += 1
interpreter.process_page(page)
layout = device.get_result() # 接收该页面的LTPage对象,里面存放着这个 page 解析出的各种对象
TEXT = ''
for x in layout:
if isinstance(x, LTTextBox):
TEXT += x.get_text()
显示信息 = f'【PDF】{FullFileName}第【{页码}】页'
DEF_RE(TEXT, 正则表达式, 显示信息)
## 无扩展名的文件,读取文件开头字节,尝试判断实际文件类型
def F_X(FullFileName, 正则表达式):
print("【注意】【无扩展名的文件】", FullFileName)
try:
f = open(FullFileName, 'rb')
except Exception as e:
print("【错误】打开失败", e)
else:
DATA = f.read(4)
f.close()
print("F_X Bytes DATA")
print(DATA)
print("文件内容编码信息", chardet.detect(DATA))
编码 = chardet.detect(DATA)['encoding']
## zip 格式
def F_ZIP(FullFileName, 正则表达式):
if zipfile.is_zipfile(FullFileName):
try:
f = zipfile.ZipFile(FullFileName)
except Exception as e:
ERROR = f'【错误】【ZIP】打开失败{e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
for i in f.namelist(): # 遍历ZIP内文件
if i.endswith('/'): # 跳过目录
pass
else:
文件名, 扩展名 = os.path.splitext(i)
print(文件名, 扩展名)
if IV_忽略文件扩展名大小写.get() == 1:
扩展名 = 扩展名.lower() # 扩展名转成小写
if 扩展名 in 扩展名集合:
try:
DATA_Bytes = f.open(i).read()
except Exception as e:
ERROR = f'【错误】【ZIP】中【{i}】打开失败{e}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
#print("DATA_Bytes", DATA_Bytes)
if 扩展名 == '.txt':
ZIP_TEXT(DATA_Bytes, 正则表达式, FullFileName+'中['+i+']文件')
else:
WARNING = f'暂不支持ZIP内{扩展名}格式直接搜索内容,请解压后再搜索'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
else:
ERROR = f'【错误】【不是ZIP格式文件】{FullFileName}'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
def 关键词转正则表达式(关键字):
正则表达式 = '(.*)'
for i in 关键字:
if i in ['^', '$', '.', '[', ']', '*', '+', '?', '{', '}', '|', '\\']:
正则表达式 += '\\' + i
else:
正则表达式 += i
正则表达式 += '(.*)'
return(正则表达式)
# 运行
def RUN(正则表达式):
## 对符合要求的文件,根据文件后缀名进行相应的操作
for i in 文件列表:
根据文件后缀名选择操作(i, 正则表达式)
INFO = '【信息】搜索结束'
Text_搜索结果文本.insert('end', INFO+'\n')
## 使用图形界面
from tkinter import *
from tkinter import filedialog # 选择文件用
from tkinter import ttk # 下拉菜单控件在ttk中
import tkinter.messagebox # 弹出提示对话框
import tkinter.simpledialog # 弹出对话框,获取用户输入
top = Tk() # 初始化Tk()
top.title('文件内容搜索工具V1.0') # 设置标题
窗口宽 = 935
窗口高 = 550
# 获取屏幕尺寸以计算布局参数,使窗口居屏幕中央
屏幕宽 = top.winfo_screenwidth()
屏幕高 = top.winfo_screenheight()
主窗口显示位置 = '%dx%d+%d+%d' % (窗口宽, 窗口高, (屏幕宽-窗口宽)/2, (屏幕高-窗口高)/2)
top.geometry(主窗口显示位置)
top.resizable(width=True, height=True) # 设置窗口是否可变长、宽(True:可变,False:不可变)
## 窗口布局
Frame_扩展名框 = Frame(top, bg='#ADFF2F')
LF_搜索目录框 = LabelFrame(top, text='选择搜索文件夹')
Frame_搜索条件框 = Frame(top)
LF_搜索结果框 = LabelFrame(top, text='搜索结果')
LF_搜索日志框 = LabelFrame(top, text='搜索日志及详细')
## 框架的位置布局
Frame_扩展名框.grid(row=0, column=0, sticky='W')
LF_搜索目录框.grid(row=1, column=0, sticky='W')
Frame_搜索条件框.grid(row=2, column=0, sticky='W')
LF_搜索结果框.grid(row=3, column=0, sticky=S+W+E+N)
LF_搜索日志框.grid(row=0, column=1, sticky=S+W+E+N, rowspan=4)
WORD_扩展名 = LabelFrame(Frame_扩展名框, text='Word')
WORD_扩展名.grid(row=0, column=0, sticky='NW')
EXCEL_扩展名 = LabelFrame(Frame_扩展名框, text='Excel')
EXCEL_扩展名.grid(row=0, column=1, sticky='NW')
PPT_扩展名 = LabelFrame(Frame_扩展名框, text='PDF')
PPT_扩展名.grid(row=0, column=2, sticky='NW')
TEXT_扩展名 = LabelFrame(Frame_扩展名框, text='TEXT')
TEXT_扩展名.grid(row=0, column=3, sticky='NW')
Other_扩展名 = LabelFrame(Frame_扩展名框, text='其他扩展名')
Other_扩展名.grid(row=0, column=4, sticky='NW')
扩展名大小写 = LabelFrame(Frame_扩展名框, text='扩展名大小写')
扩展名大小写.grid(row=0, column=5, sticky='NW')
## Python全局变量
扩展名集合 = set()
文件列表 = []
## 图形全局变量
复选_TXT = IntVar()
复选_XML = IntVar()
复选_JSON = IntVar()
复选_CSV = IntVar()
复选_XLSX = IntVar()
复选_XLS = IntVar()
复选_DOC = IntVar()
复选_DOCX = IntVar()
复选_PPTX = IntVar()
复选_PPT = IntVar()
复选_PDF = IntVar()
复选_NULL = IntVar()
复选_ZIP = IntVar()
IV_忽略文件扩展名大小写 = IntVar()
IV_忽略文件扩展名大小写.set(1) # 设置默认选择
IV_忽略搜索关键字大小写 = IntVar()
SV_搜索关键字 = StringVar()
SV_正则表达式 = StringVar()
搜索目录 = StringVar()
## 图形操作函数
def DEF_使用关键字搜索():
扩展名集合.clear() # 每次执行搜索前,先清空全局集合变量,防止累加
if 复选_TXT.get() == 1:
扩展名集合.add('.txt')
if 复选_XML.get() == 1:
扩展名集合.add('.xml')
if 复选_JSON.get() == 1:
扩展名集合.add('.json')
if 复选_CSV.get() == 1:
扩展名集合.add('.csv')
if 复选_XLSX.get() == 1:
扩展名集合.add('.xlsx')
if 复选_XLS.get() == 1:
扩展名集合.add('.xls')
if 复选_DOC.get() == 1:
扩展名集合.add('.doc')
if 复选_DOCX.get() == 1:
扩展名集合.add('.docx')
if 复选_PPTX.get() == 1:
扩展名集合.add('.pptx')
if 复选_PDF.get() == 1:
扩展名集合.add('.pdf')
if 复选_NULL.get() == 1:
扩展名集合.add('')
if 复选_ZIP.get() == 1:
扩展名集合.add('.zip')
if 扩展名集合 == set():
ERROR = '未选择扩展名'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
if SV_搜索关键字.get() == '':
Text_搜索日志文本.delete(0.0, 'end')
ERROR = '未设置搜索关键字'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
if 搜索目录.get() == '':
Text_搜索日志文本.delete(0.0, 'end')
ERROR = '未设置搜索文件夹'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
DEBUG = f'【调试】开始搜索目录{搜索目录.get()}'
Text_搜索日志文本.insert('end', DEBUG+'\n')
## 初始化
文件列表.clear() # 每次执行搜索前,先清空全局列表变量,防止累加
正则表达式 = 关键词转正则表达式(SV_搜索关键字.get())
## 清空两个文本框内容
Text_搜索日志文本.delete(0.0, 'end')
Text_搜索结果文本.delete(0.0, 'end')
## 搜索目录下所有文件,找出符合要求的文件列表
DIR_init(搜索目录.get())
if 文件列表 == []:
Text_搜索日志文本.delete(0.0, 'end')
Text_搜索结果文本.delete(0.0, 'end')
WARNING = '【注意】未找到相应扩展名的文件'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
else:
INFO = f'【信息】找到符合扩展名条件的文件【{len(文件列表)}】个'
Text_搜索日志文本.insert('end', INFO+'\n')
for 文件名, 扩展名 in 文件列表:
INFO = f'{扩展名}\t{文件名}'
Text_搜索日志文本.insert('end', INFO+'\n')
## 对符合要求的文件,根据文件后缀名进行相应的操作
th=threading.Thread(target=RUN, args=(正则表达式,))
th.setDaemon(True) # 守护线程
th.start()
def DEF_使用正则搜索():
扩展名集合.clear() # 每次执行搜索前,先清空全局集合变量,防止累加
if 复选_TXT.get() == 1:
扩展名集合.add('.txt')
if 复选_XML.get() == 1:
扩展名集合.add('.xml')
if 复选_JSON.get() == 1:
扩展名集合.add('.json')
if 复选_CSV.get() == 1:
扩展名集合.add('.csv')
if 复选_XLSX.get() == 1:
扩展名集合.add('.xlsx')
if 复选_XLS.get() == 1:
扩展名集合.add('.xls')
if 复选_DOC.get() == 1:
扩展名集合.add('.doc')
if 复选_DOCX.get() == 1:
扩展名集合.add('.docx')
if 复选_PPTX.get() == 1:
扩展名集合.add('.pptx')
if 复选_PDF.get() == 1:
扩展名集合.add('.pdf')
if 复选_NULL.get() == 1:
扩展名集合.add('')
if 复选_ZIP.get() == 1:
扩展名集合.add('.zip')
if 扩展名集合 == set():
ERROR = '未选择扩展名'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
if SV_正则表达式.get() == '':
Text_搜索日志文本.delete(0.0, 'end')
ERROR = '未设置正则表达式'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
if 搜索目录.get() == '':
Text_搜索日志文本.delete(0.0, 'end')
ERROR = '未设置搜索文件夹'
Text_搜索日志文本.insert('end', ERROR+'\n', 'tag_error')
else:
DEBUG = f'【调试】开始搜索目录{搜索目录.get()}'
Text_搜索日志文本.insert('end', DEBUG+'\n')
## 初始化
文件列表.clear() # 每次执行搜索前,先清空全局列表变量,防止累加
正则表达式 = SV_正则表达式.get()
## 清空两个文本框内容
Text_搜索日志文本.delete(0.0, 'end')
Text_搜索结果文本.delete(0.0, 'end')
## 搜索目录下所有文件,找出符合要求的文件列表
DIR_init(搜索目录.get())
if 文件列表 == []:
Text_搜索日志文本.delete(0.0, 'end')
Text_搜索结果文本.delete(0.0, 'end')
WARNING = '【注意】未找到相应扩展名的文件'
Text_搜索日志文本.insert('end', WARNING+'\n', 'tag_warning')
else:
INFO = f'【信息】找到符合扩展名条件的文件【{len(文件列表)}】个'
Text_搜索日志文本.insert('end', INFO+'\n')
for 文件名, 扩展名 in 文件列表:
INFO = f'{扩展名}\t{文件名}'
Text_搜索日志文本.insert('end', INFO+'\n')
## 对符合要求的文件,根据文件后缀名进行相应的操作
th=threading.Thread(target=RUN, args=(正则表达式,))
th.setDaemon(True) # 守护线程
th.start()
def DEF_按钮_选择目录():
选择的目录 = filedialog.askdirectory()
搜索目录.set(选择的目录) # 实时更新显示
## 图形控件
Checkbutton(WORD_扩展名, text="docx ", variable=复选_DOCX).grid(row=0, column=0, sticky='NW')
Checkbutton(WORD_扩展名, text="doc ", variable=复选_DOC).grid(row=1, column=0, sticky='NW')
Checkbutton(EXCEL_扩展名, text="xlsx ", variable=复选_XLSX).grid(row=0, column=0, sticky='NW')
Checkbutton(EXCEL_扩展名, text="xls ", variable=复选_XLS).grid(row=1, column=0, sticky='NW')
Checkbutton(EXCEL_扩展名, text="csv ", variable=复选_CSV).grid(row=2, column=0, sticky='NW')
Checkbutton(PPT_扩展名, text="pptx ", variable=复选_PPTX).grid(row=0, column=0, sticky='NW')
XX = Checkbutton(PPT_扩展名, text="ppt ", variable=复选_PPT)
XX.grid(row=1, column=0, sticky='NW')
XX.configure(state='disabled')
Checkbutton(TEXT_扩展名, text="txt ", variable=复选_TXT).grid(row=0, column=0, sticky='NW')
Checkbutton(TEXT_扩展名, text="xml ", variable=复选_XML).grid(row=1, column=0, sticky='NW')
Checkbutton(TEXT_扩展名, text="json ", variable=复选_JSON).grid(row=2, column=0, sticky='NW')
Checkbutton(Other_扩展名, text="无扩展名", variable=复选_NULL).grid(row=0, column=0, sticky='NW')
Checkbutton(Other_扩展名, text="zip", variable=复选_ZIP).grid(row=1, column=0, sticky='NW')
Checkbutton(Other_扩展名, text="pdf ", variable=复选_PDF).grid(row=2, column=0, sticky='NW')
Checkbutton(扩展名大小写, text="忽略大小写", variable=IV_忽略文件扩展名大小写).grid(row=0, column=0)
LF_关键字搜索框 = LabelFrame(Frame_搜索条件框, text='使用关键字搜索')
LF_正则表达式框 = LabelFrame(Frame_搜索条件框, text='使用正则搜索')
LF_关键字搜索框.grid(row=0, column=0, sticky='NW')
LF_正则表达式框.grid(row=0, column=1, sticky='NW')
Label(LF_关键字搜索框, text='搜索关键字').grid(row=0,column=0,sticky='NW')
Entry(LF_关键字搜索框, textvariable=SV_搜索关键字, width=32).grid(row=1, column=0, sticky='NW', columnspan=2)
Button(LF_关键字搜索框, text='开始搜索', command=DEF_使用关键字搜索).grid(row=3, column=0, sticky='W')
Checkbutton(LF_关键字搜索框, text="忽略大小写 ", variable=IV_忽略搜索关键字大小写).grid(row=3, column=1, sticky='E')
Label(LF_正则表达式框, text='RE正则表达式').grid(row=0,column=0,sticky='NW')
Entry(LF_正则表达式框, textvariable=SV_正则表达式, width=32).grid(row=1, column=0, sticky='NW', columnspan=2)
Button(LF_正则表达式框, text='开始搜索', command=DEF_使用正则搜索).grid(row=3, column=0, sticky='W')
Checkbutton(LF_正则表达式框, text="忽略大小写 ", variable=IV_忽略搜索关键字大小写).grid(row=3, column=1, sticky='E')
Button(LF_搜索目录框, text=' 选择 ', command=DEF_按钮_选择目录).grid(row=1, column=0, sticky='W')
Entry(LF_搜索目录框, textvariable=搜索目录, width=59).grid(row=1, column=1)
## LF_搜索结果框
Text_搜索结果文本 = Text(LF_搜索结果框, width=63, height=20, wrap='word') # wrap='none' 不自动换行, wrap='word' 自动换行
Scrollbar_XX_列表_竖 = Scrollbar(LF_搜索结果框)
Scrollbar_XX_列表_竖['command'] = Text_搜索结果文本.yview
#Scrollbar_XX_列表_横 = Scrollbar(LF_搜索结果框)
#Scrollbar_XX_列表_横['command'] = Text_搜索结果文本.xview
#Scrollbar_XX_列表_横['orient'] = HORIZONTAL
Text_搜索结果文本.grid(row=0, column=0, sticky=S+W+E+N)
Scrollbar_XX_列表_竖.grid(row=0, column=1, sticky=S+W+E+N)
#Scrollbar_XX_列表_横.grid(row=1, column=0, sticky=S+W+E+N)
# 自动设置滚动条滑动幅度
Text_搜索结果文本['yscrollcommand'] = Scrollbar_XX_列表_竖.set
#Text_搜索结果文本.config(xscrollcommand=Scrollbar_XX_列表_横.set)
## LF_搜索日志框
Text_搜索日志文本 = Text(LF_搜索日志框, width=63, height=39, wrap='none') # wrap='none' 不自动换行, wrap='word' 自动换行
Scrollbar_XXX_列表_竖 = Scrollbar(LF_搜索日志框)
Scrollbar_XXX_列表_竖['command'] = Text_搜索日志文本.yview
Scrollbar_XXX_列表_横 = Scrollbar(LF_搜索日志框)
Scrollbar_XXX_列表_横['command'] = Text_搜索日志文本.xview
Scrollbar_XXX_列表_横['orient'] = HORIZONTAL
Text_搜索日志文本.grid(row=0, column=0, sticky=S+W+E+N)
Scrollbar_XXX_列表_竖.grid(row=0, column=1, sticky=S+W+E+N)
Scrollbar_XXX_列表_横.grid(row=1, column=0, sticky=S+W+E+N)
# 自动设置滚动条滑动幅度
Text_搜索日志文本['yscrollcommand'] = Scrollbar_XXX_列表_竖.set
Text_搜索日志文本.config(xscrollcommand=Scrollbar_XXX_列表_横.set)
# 自定义文本格式
Text_搜索日志文本.tag_config('tag_error', backgroun='yellow', foreground='red')
Text_搜索日志文本.tag_config('tag_warning', backgroun='yellow')
## 进入消息循环
top.mainloop()