初始归档:健康管理资料库(大医网/药膳/体质监测/中医理论等12个资料集,7712个文件)

This commit is contained in:
512song committed 2026-09-23 21:59:25 +08:00
commit 80ae3811cf
7712 files changed
+4628547

No files matched your search

@@ -0,0 +1,122 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
辅行诀五脏用药法要-药性探真 资料库 ETL 第 9 步(2026-09-17):**归档一致性审计**
用途:任意时刻复核「文档里引用的 md5 / 文件是否存在 / 有无残留」是否与库内实际一致。
检查项:
① 全库 md5 索引(排除 . 与 __pycache__)
② 关键文档中出现的完整 md5(32 位)与缩写 md5(前 8 位 + …)能否对应到现有文件
③ 若为历史值(确属旧版本留痕),输出 ⚠ 提示但不算错;无法对应且非历史值者列 ❌
④ 残留检查:__pycache__、.bak/.tmp/~ 备份、空目录
只读,不修改任何文件;退出码:有 ❌ 时返回 1,便于脚本化校验。
"""
import os, re, sys, hashlib, glob
BASE = os.path.expanduser("~/Documents/ai_agent_scraper_study/data/辅行诀五脏用药法要-药性探真")
DOCS = ["README.md", "01_来源数据/来源说明.md", "01_来源数据/校核参考/README.md",
"02_加工数据/药性探真_第1章_检查报告.md", "02_加工数据/药性探真_第1章_待核对清单.md",
"02_加工数据/药性探真_第2章_检查报告.md", "02_加工数据/药性探真_第2章_待核对清单.md",
"02_加工数据/药性探真_第3章_检查报告.md", "02_加工数据/药性探真_第3章_待核对清单.md",
"02_加工数据/药性探真_第1-3章_合并结构.json",
"02_加工数据/整订稿清洗报告.md", "02_加工数据/印刷本清洗报告.md", "02_加工数据/文本清洗报告.md",
"02_加工数据/原文清洗报告.md", "02_加工数据/人工核对清单.md", "02_加工数据/印刷本人工核对清单.md",
"03_关联融合/README.md", "03_关联融合/整订稿核对报告.md", "03_关联融合/整订稿-底本_方目对照表.md",
"03_关联融合/药性探真-底本_药名方目对照表.md", "03_关联融合/药性探真-底本_核对报告.md",
"03_关联融合/药性探真-底本_药名方目对照.json",
"04_分析报告/README.md"]
# 已知历史值(旧版本留痕,出现即视为正常)
KNOWN_HISTORIC = {
"ce800838b94512a00fbe8375570eb180", # 药性探真_第一章_清洗版.md 旧 md5(2026-09-17 重跑前)
"e550bb651e026fb3a314a90faaa9937e", # 底本基础文本旧 md5(人工核验回填前)
"0cea9938547ac8c1a0e9479cbda15e47", # 《…》第1章.md 标题层级优化前(快照现存库内,故通常能直接命中)
"29097b725de0e3e5829a5c0acb132074", # 第2章清洗版(「拟正字」6 条 11 处订正前;README 更新日志(五)全值留痕)
}
# 旧值缩写(更新日志里刻意留痕的「改前 → 改后」写法,出现即视为正常)
HISTORIC_PREFIX = {"5642e2d0", "ce800838", "e550bb65",
"65c63d90", "978d57c9", # 第2章 检查报告/待核对清单 第1批判决回填时值
"52f79d41", "d76d710d", # 第2章 检查报告/待核对清单 第2批判决回填时值
"44eeca76", # 第2章 结构.json 第2批判决回填时值
"8a377e1e", # 第2章 清洗版(第1–3批判决期间值,第4批据核改后变更)
"cd754c58", "45de11c7", "ecf80e86", # 第2章 报告/清单/结构 第3批判决回填时值
"e490eb85", "234bd0a3", "12d75c0e", # 第2章 报告/清单/脚本 第4批判决回填时值
"859450c5", "d64de6e5", "2b571161", # 第2章 报告/清单/脚本 「保留」归一(词表)时值
"3511f9b3", "20a2d8c2", # 第2章 脚本 7.x 重排/待补正字标记中间值
"29097b72", "c51ad6da", "8d6e4e24", # 第2章 清洗版/报告/清单 「拟正字」落盘前时值
"84ab1c43", "b435e320", # 第2章 结构/脚本 同期时值
"bee344b7", "ff367101", "93e003f8", # 第2章 报告/结构/脚本 行号更正前时值
"433a6a0a", "b0c7ff33", "db0b6227", # 第2章 报告/结构/脚本 「原书用字」栏补入前时值
"347aecce", "a0094713", # 第1章 报告/结构 引文异文登记前时值
"09087b8e", "b5d23ecc", "8926e4fe", "196f3678", # 第2章 报告/清单/结构/脚本 层级优化前时值
"716e4c56", "4acc6455", # 第1章 报告/结构 引文异文登记(待核)时值
"d838a537", # 07_clean_ch1.py 引文登记(待核)时值
"3e4f50b3", "c970c608", "ed85e822", # 第3章 报告/结构/脚本 判决回填前时值(更新日志(十三)留痕)
"2c5378bd", "c18175f8", "575f94a7", "6e01d28e", "bcd90aa3", # 第3章 第2批判决前时值((十四)(十五) 留痕)
"e68c05cb", "05cdbbf5", "9e4b2aad", "7833650f", "b0783fb3", # 第3章 第3批判决前时值((十五)(十六) 留痕)
"194a913c", "86fb7658", "3fd5855b", "61c2fea3", "42c16ad4",
"71d6ac95", "e542d14c", # 第3章 报告/脚本 中间时值((十七)留痕)
"b221786e", "391a6454", "8cf5aecb", "dcd37b8a", "ac7d8774",
"f191685e", "ac511120", # 第3章 清单/脚本 中间时值((十八)留痕) # 第3章 第5批判决前时值((十七)(十八) 留痕) # 第3章 第4批判决前时值((十六)(十七) 留痕)
"72482eed", "af0e2cdb", "74cb970a", # 第3章 清单/结构/脚本 存疑补录前时值(更新日志(十三)前中间值)
"f9611535", "8b40d02f", "672e2133", "48752a23", # 第3章 报告/脚本 行标与体例精简中间值
"c406a03f", "70b00b0f", "76063838", "97a7b47a", # 第3章 报告/清单/结构/脚本 第 6 批判决(#56)前时值(更新日志(十八)「新值」→(二十)「改前」)
"04919121", "7988ddb9", "8b3ce170", "32399f74", # 第3章 报告/清单/结构/脚本 第 7 批(源件层级优化等)前时值(更新日志(二十)「新值」→(二十一)「改前」)
}
def md5_of(p):
return hashlib.md5(open(p, "rb").read()).hexdigest()
def main():
files = {}
for root, dirs, fs in os.walk(BASE):
dirs[:] = [d for d in dirs if not d.startswith((".", "__"))]
for f in fs:
p = os.path.join(root, f)
files[os.path.relpath(p, BASE)] = md5_of(p)
full = {v: k for k, v in files.items()}
pref = {}
for k, v in files.items():
pref.setdefault(v[:8], []).append(k)
print(f"库内文件 {len(files)} 个\n")
bad = 0
for d in DOCS:
p = os.path.join(BASE, d)
if not os.path.exists(p):
print(f" ❌ 文档缺失:{d}")
bad += 1
continue
txt = open(p, encoding="utf-8").read()
for m in sorted(set(re.findall(r"\b[0-9a-f]{32}\b", txt))):
if m in full:
print(f" ✅ {d[:34]:<36} {m[:12]}… → {full[m]}")
elif m in KNOWN_HISTORIC:
print(f" ⚠ {d[:34]:<36} {m[:12]}… → 历史值(旧版本留痕,正常)")
else:
print(f" ❌ {d[:34]:<36} {m[:12]}… → 库内无此 md5")
bad += 1
for m in sorted(set(re.findall(r"`([0-9a-f]{8})…`", txt))):
if m in pref:
print(f" ✅ {d[:34]:<36} {m}… → {'、'.join(pref[m])}")
elif m in HISTORIC_PREFIX:
print(f" ⚠ {d[:34]:<36} {m}… → 历史值缩写(更新日志「改前」留痕,正常)")
else:
print(f" ❌ {d[:34]:<36} {m}… → 库内无此文件(缩写)")
bad += 1
print("\n残留检查:")
pyc = glob.glob(os.path.join(BASE, "**/__pycache__"), recursive=True)
tmp = [f for f in files if f.endswith((".bak", ".tmp", "~"))]
empt = [os.path.relpath(r, BASE) for r, ds, fs in os.walk(BASE) if not ds and not fs
and not r.endswith((".git",))]
print(f" __pycache__: {pyc or '无'}")
print(f" 备份/临时文件: {tmp or '无'}")
print(f" 空目录: {empt or '无'}")
print(f"\n审计结果:{'通过(无 ❌)' if bad == 0 else f'有 {bad} 处 ❌ 需修正'}")
return 0 if bad == 0 else 1
if __name__ == "__main__":
sys.exit(main())