我的知识记录

Python按文件内容搜索文字教程

用Python递归扫描文件夹,按文件正文内容搜索关键词,支持txt、md、py等文本文件,逐行匹配并输出命中位置,比系统搜索精准可控。

场景痛点

只记得某份文档里写过"2025年度预算"这句话,但文件名完全没印象,Windows全局搜文件名根本找不到。手动打开一个个文档Ctrl+F,几百个文件能查到下班。用Python直接读文件正文做关键词匹配,文本类文件几秒扫完,命中的文件路径和行号一起打出来,直接定位到那句话。

用到的库

pip install openpyxl

核心用标准库 ospathlibchardet(可选,用于探测编码),导出结果用 openpyxl

完整代码

import os
from pathlib import Path
from openpyxl import Workbook


# 需要扫描的文本类后缀
TEXT_EXTS = {".txt", ".md", ".py", ".js", ".html", ".css", ".json",
".csv", ".log", ".xml", ".ini", ".cfg", ".bat", ".sh"}


def read_text_safe(file_path: Path):
"""尝试用常见编码读取文本文件,失败则返回 None。"""
for enc in ("utf-8", "gbk", "gb18030", "latin-1"):
try:
return file_path.read_text(encoding=enc)
except (UnicodeDecodeError, OSError):
continue
return None


def search_content(root_dir: str, keyword: str,
extensions: set = None,
case_sensitive: bool = False):
"""递归搜索文件内容中包含关键词的文件,返回命中清单。"""
root = Path(root_dir)
exts = extensions or TEXT_EXTS
kw = keyword if case_sensitive else keyword.lower()
results = []

for dirpath, _, filenames in os.walk(root):
for name in filenames:
p = Path(dirpath) / name
if p.suffix.lower() not in exts:
continue
# 跳过过大的文件,防止卡住
try:
if p.stat().st_size > 50 * 1024 * 1024:
continue
except OSError:
continue

text = read_text_safe(p)
if text is None:
continue

haystack = text if case_sensitive else text.lower()
if kw in haystack:
# 找到第一个命中的行号
hit_lines = []
for lineno, line in enumerate(text.splitlines(), 1):
target = line if case_sensitive else line.lower()
if kw in target:
hit_lines.append((lineno, line.strip()[:120]))
if len(hit_lines) >= 3:
break
results.append({
"path": str(p),
"hits": hit_lines,
})

return results


def export_to_excel(results: list, out_path: str):
wb = Workbook()
ws = wb.active
ws.title = "内容搜索结果"
ws.append(["序号", "文件路径", "命中行号", "命中内容片段"])
row = 1
for item in results:
for lineno, snippet in item["hits"]:
row += 1
ws.append([row, item["path"], lineno, snippet])
ws.column_dimensions['A'].width = 8
ws.column_dimensions['B'].width = 80
ws.column_dimensions['C'].width = 10
ws.column_dimensions['D'].width = 80
wb.save(out_path)


if __name__ == "__main__":
ROOT = r"D:\工作资料"
KEYWORD = "年度预算"

results = search_content(ROOT, KEYWORD)
print(f"共在 {len(results)} 个文件中找到「{KEYWORD}」:\n")
for item in results:
print("文件:", item["path"])
for lineno, snippet in item["hits"]:
print(f"   第{lineno}行: {snippet}")
print()

export_to_excel(results, r"D:\工作资料\内容搜索结果.xlsx")
print("结果已导出:D:\\工作资料\\内容搜索结果.xlsx")

代码讲解

read_text_safe 是这段代码的核心:中文Windows下的文件编码五花八门,UTF-8、GBK、GB18030都常见,逐个编码尝试读取,哪个成功用哪个,最后兜底 latin-1(它能吃下任意字节不报错,但中文会乱码,只用于保底)。TEXT_EXTS 限定只扫文本类文件,.docx.xlsx.pdf 是二进制压缩格式,直接读会乱码,不在这篇范围内。超过50MB的文件直接跳过,避免把日志大文件拖慢。命中后记录行号和前120字符的片段,最多记3处,够定位就行。Excel导出时把每个命中行拆成一行,方便按行号跳转。

运行结果

控制台逐文件打印命中路径和行号片段,最后在根目录生成 内容搜索结果.xlsx,四列:序号、文件路径、命中行号、命中内容片段。复制文件路径就能直接打开对应文件。

注意事项

  • .docx.xlsx.pdf 不能直接当文本读,需要用 python-docxopenpyxlpdfplumber 这类库先解析,本篇不展开。
  • 编码尝试顺序很重要:先UTF-8再GBK,顺序反了中文可能读成乱码但不报错。
  • 二进制文件(图片、视频、exe)不要扫,里面随机字节偶尔会误命中关键词,还拖慢速度。
  • 搜整个C盘会很慢且有权限问题,建议先锁定具体业务目录。

Python按文件内容搜索文字教程

标签:

更新时间:2026-09-14 21:15:48

上一篇:Python按文件名关键词搜索文件教程

下一篇:Python遍历文件夹递归找文件:pathlib与os.walk两种写法