# ①book_splitter.py · 切书脚本 · 2026-05-21 ```jsx HLDP://juzi/tools/book_splitter/2026-05-21 ├── 作用: 把 txt 文件按章节切块存入知识库 ├── 操作: 整段复制粘贴到终端,回车 └── 看到「✅ book_splitter.py 创建完成」就成功了 ``` --- ## 复制这整段到终端,回车 ```bash cat > ~/chenxing-aircraft/tools/book_splitter.py << 'ENDOFFILE' #!/usr/bin/env python3 """ 书籍分块工具 · book_splitter.py 把 txt 文件按章节切块存入知识库 用法: python3 tools/book_splitter.py --file 折春漪.txt --book 折春漪 """ import argparse import re import sqlite3 import sys from pathlib import Path BASE_DIR = Path(__file__).parent.parent DB_PATH = BASE_DIR / "chenxing.db" def split_by_chapters(text: str, chapters_per_chunk: int = 2) -> list: """按章节标题切割""" patterns = [ r'第[零一二三四五六七八九十百千0-9]+章[\s\u3000]', r'第[零一二三四五六七八九十百千0-9]+章$', r'Chapter\s+\d+', ] combined = '|'.join(f'(?:{p})' for p in patterns) positions = [(m.start(), m.group().strip()) for m in re.finditer(combined, text, re.MULTILINE)] if not positions: print("⚠️ 未找到章节标题,按5000字切割") chunks = [] for i, start in enumerate(range(0, len(text), 5000)): chunks.append({"title": f"第{i+1}块", "content": text[start:start+5000]}) return chunks chapters = [] for i, (pos, title) in enumerate(positions): end = positions[i+1][0] if i+1 < len(positions) else len(text) chapters.append({"title": title, "content": text[pos:end]}) chunks = [] for i in range(0, len(chapters), chapters_per_chunk): batch = chapters[i:i+chapters_per_chunk] if len(batch) > 1: combined_title = f"{batch[0]['title']}-{batch[-1]['title']}" else: combined_title = batch[0]['title'] chunks.append({ "title": combined_title, "content": "\n\n".join(c["content"] for c in batch) }) return chunks def import_to_knowledge(book_name: str, chunks: list, user_id: int = 1): """导入到知识库""" conn = sqlite3.connect(str(DB_PATH)) imported = skipped = 0 try: for chunk in chunks: title = f"《{book_name}》{chunk['title']}" existing = conn.execute( "SELECT id FROM knowledge WHERE title=? AND user_id=?", (title, user_id) ).fetchone() if existing: skipped += 1 continue conn.execute( """INSERT INTO knowledge (user_id,title,content,category,tags,source) VALUES (?,?,?,'book',?,?)""", (user_id, title, chunk["content"], book_name, f"书籍分块·{book_name}") ) imported += 1 conn.commit() print(f"✅ 导入完成:新增 {imported} 块,跳过 {skipped} 块(已存在)") return imported finally: conn.close() if __name__ == "__main__": parser = argparse.ArgumentParser(description="书籍分块导入知识库") parser.add_argument("--file", required=True, help="书籍 txt 文件路径") parser.add_argument("--book", required=True, help="书名(不含《》)") parser.add_argument("--chunks", type=int, default=2, help="每块几章(默认2)") parser.add_argument("--user_id", type=int, default=1, help="用户ID(默认1)") args = parser.parse_args() fp = Path(args.file) if not fp.exists(): print(f"❌ 文件不存在:{args.file}") sys.exit(1) text = fp.read_text(encoding="utf-8", errors="ignore") print(f"📚 书名:《{args.book}》") print(f"📏 总字数:{len(text):,}") chunks = split_by_chapters(text, args.chunks) print(f"✂️ 共切割为 {len(chunks)} 块(每块约 {args.chunks} 章)") import_to_knowledge(args.book, chunks, args.user_id) ENDOFFILE echo "✅ book_splitter.py 创建完成" ``` --- > 看到 `✅ book_splitter.py 创建完成` → 告诉宝宝,进行下一步 💜 >