每日备份 2026-06-10 12:57:13
This commit is contained in:
1 parent
fda2ccb8c2
commit
3d2e638c6a
244 files changed
+58890
-3
No files matched your search
@@ -0,0 +1,341 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# 程序名称: novel-format-check.sh
|
||||
# ============================================================================
|
||||
# 功能描述: 小说写作规范检查模块,自动校验格式、字数、描写标准
|
||||
# ============================================================================
|
||||
# 设计目的:
|
||||
# 1. 检查章节格式规范(禁止Markdown标题、分隔线等)
|
||||
# 2. 校验字数标准(5000-8000字)
|
||||
# 3. 评估描写标准(内心独白、动作描写、对话、环境描写)
|
||||
# 4. 检查禁止项(沉默良久、省略号、过渡词)
|
||||
# 5. 生成检查报告并计算总分
|
||||
# ============================================================================
|
||||
# 输入参数:
|
||||
# $1: 章节文件名(可选,默认检查最新章节)
|
||||
# ============================================================================
|
||||
# 输出:
|
||||
# 标准输出: 检查结果
|
||||
# 文件: ${章节名}-检查报告.md
|
||||
# ============================================================================
|
||||
# 依赖:
|
||||
# - grep, sed, wc, bc
|
||||
# - /root/.openclaw/workspace/平安书 目录
|
||||
# ============================================================================
|
||||
# 作者: 青龙 (OpenClaw AI)
|
||||
# 创建时间: 2026-02-13
|
||||
# 更新: 2026-02-13 v1.1 修复逻辑错误
|
||||
# ============================================================================
|
||||
# 检查清单:
|
||||
# [x] 头部注释完整
|
||||
# [x] grep错误处理 (2>/dev/null)
|
||||
# [x] 空值处理 ([ -z "$var" ])
|
||||
# [x] 返回值处理 ($?)
|
||||
# [x] 语法检查 (bash -n)
|
||||
# ============================================================================
|
||||
|
||||
NOVEL_DIR="/root/.openclaw/workspace/平安书"
|
||||
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
|
||||
|
||||
# ============================================================================
|
||||
# 1. 检查格式规范
|
||||
# ============================================================================
|
||||
check_format() {
|
||||
local chapter="$1"
|
||||
|
||||
local errors=""
|
||||
|
||||
# 检查Markdown标题
|
||||
if grep -q "^#" "$chapter" 2>/dev/null; then
|
||||
errors="${errors}❌ 包含Markdown标题\n"
|
||||
fi
|
||||
|
||||
# 检查分隔线
|
||||
if grep -q "^---" "$chapter" 2>/dev/null; then
|
||||
errors="${errors}❌ 包含分隔线\n"
|
||||
fi
|
||||
|
||||
# 检查章节小节
|
||||
if grep -q "^## " "$chapter" 2>/dev/null; then
|
||||
errors="${errors}❌ 包含章节小节\n"
|
||||
fi
|
||||
|
||||
# 检查章节落款
|
||||
if grep -qE "第[0-9]+章.*完" "$chapter" 2>/dev/null; then
|
||||
errors="${errors}❌ 包含章节落款\n"
|
||||
fi
|
||||
|
||||
# 检查**加粗标记(纯文本禁止任何Markdown格式)
|
||||
if grep -q "\*\*" "$chapter" 2>/dev/null; then
|
||||
local count=$(grep -c "\*\*" "$chapter")
|
||||
errors="${errors}❌ 包含${count}处**加粗标记(纯文本禁止Markdown格式)\n"
|
||||
fi
|
||||
|
||||
if [ -z "$errors" ]; then
|
||||
echo "✅ 格式规范: 通过"
|
||||
return 0
|
||||
else
|
||||
echo "⚠️ 格式规范: 存在问题"
|
||||
echo -e "$errors"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 2. 检查字数标准
|
||||
# ============================================================================
|
||||
check_length() {
|
||||
local chapter="$1"
|
||||
|
||||
# 使用Python精确统计纯汉字数
|
||||
# wc -m 统计所有字符(含标点),需要去除
|
||||
local char_count=$(python3 -c "
|
||||
import sys
|
||||
with open('$chapter', 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
# 只统计汉字
|
||||
count = sum(1 for c in content if '\u4e00' <= c <= '\u9fff')
|
||||
print(count)
|
||||
" 2>/dev/null)
|
||||
|
||||
[ -z "$char_count" ] && char_count=0
|
||||
|
||||
echo " 字数统计: $char_count 字"
|
||||
|
||||
if [ $char_count -ge 5000 ] && [ $char_count -le 8000 ]; then
|
||||
echo " ✅ 字数标准: 符合 (5000-8000)"
|
||||
return 0
|
||||
elif [ $char_count -lt 5000 ]; then
|
||||
local diff=$((5000 - char_count))
|
||||
echo " ⚠️ 字数标准: 不足 (需+$diff字)"
|
||||
return 1
|
||||
else
|
||||
local diff=$((char_count - 8000))
|
||||
echo " ⚠️ 字数标准: 超出 (需-$diff字)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 3. 检查描写标准
|
||||
# ============================================================================
|
||||
check_description() {
|
||||
local chapter="$1"
|
||||
|
||||
# 内心独白
|
||||
local inner=$(grep -cE "想道|心中|暗自|默念|忖道" "$chapter" 2>/dev/null)
|
||||
[ -z "$inner" ] && inner=0
|
||||
echo " 内心独白: $inner 处"
|
||||
|
||||
# 动作描写关键词
|
||||
local action=$(grep -cE "身形|身形一|伸手|抬手|迈步|纵身|疾驰|飞奔" "$chapter" 2>/dev/null)
|
||||
[ -z "$action" ] && action=0
|
||||
echo " 动作描写: $action 处"
|
||||
|
||||
# 对话
|
||||
local dialogue=$(grep -c "「\|”" "$chapter" 2>/dev/null)
|
||||
[ -z "$dialogue" ] && dialogue=0
|
||||
dialogue=$((dialogue / 2))
|
||||
echo " 对话数量: $dialogue 段"
|
||||
|
||||
# 环境描写
|
||||
local env_count=$(grep -cE "天空|山林|月光|风声|树叶|流水" "$chapter" 2>/dev/null)
|
||||
[ -z "$env_count" ] && env_count=0
|
||||
echo " 环境描写: $env_count 处"
|
||||
|
||||
# 评分
|
||||
local score=0
|
||||
|
||||
if [ $inner -ge 3 ]; then
|
||||
score=$((score + 25))
|
||||
echo " ✅ 内心独白: 符合 (≥3)"
|
||||
else
|
||||
echo " ⚠️ 内心独白: 不足 (<3)"
|
||||
fi
|
||||
|
||||
if [ $action -ge 3 ]; then
|
||||
score=$((score + 25))
|
||||
echo " ✅ 动作描写: 符合 (≥3)"
|
||||
else
|
||||
echo " ⚠️ 动作描写: 不足 (<3)"
|
||||
fi
|
||||
|
||||
if [ $dialogue -ge 4 ]; then
|
||||
score=$((score + 25))
|
||||
echo " ✅ 对话数量: 符合 (≥4)"
|
||||
else
|
||||
echo " ⚠️ 对话数量: 不足 (<4)"
|
||||
fi
|
||||
|
||||
if [ $env_count -ge 5 ]; then
|
||||
score=$((score + 25))
|
||||
echo " ✅ 环境描写: 符合 (≥5)"
|
||||
else
|
||||
echo " ⚠️ 环境描写: 不足 (<5)"
|
||||
fi
|
||||
|
||||
echo " 📊 描写评分: $score/100"
|
||||
|
||||
if [ $score -ge 75 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 4. 检查禁止项
|
||||
# ============================================================================
|
||||
check_prohibited() {
|
||||
local chapter="$1"
|
||||
|
||||
local violations=0
|
||||
|
||||
# 沉默良久
|
||||
local silence=$(grep -c "沉默良久" "$chapter" 2>/dev/null)
|
||||
[ -z "$silence" ] && silence=0
|
||||
if [ $silence -gt 2 ]; then
|
||||
echo " ⚠️ '沉默良久': $silence 次 (应≤2)"
|
||||
violations=$((violations + 1))
|
||||
else
|
||||
echo " ✅ '沉默良久': $silence 次 (≤2)"
|
||||
fi
|
||||
|
||||
# 省略号(中文省略号)
|
||||
local ellipsis=$(grep -c "……" "$chapter" 2>/dev/null)
|
||||
[ -z "$ellipsis" ] && ellipsis=0
|
||||
if [ $ellipsis -gt 5 ]; then
|
||||
echo " ⚠️ '……': $ellipsis 次 (应≤5)"
|
||||
violations=$((violations + 1))
|
||||
else
|
||||
echo " ✅ '……': $ellipsis 次 (≤5)"
|
||||
fi
|
||||
|
||||
# 过渡段落
|
||||
local transition=$(grep -cE "不多时|片刻之后|过了一会儿" "$chapter" 2>/dev/null)
|
||||
[ -z "$transition" ] && transition=0
|
||||
if [ $transition -gt 3 ]; then
|
||||
echo " ⚠️ 过渡词: $transition 次 (应≤3)"
|
||||
else
|
||||
echo " ✅ 过渡词: $transition 次 (≤3)"
|
||||
fi
|
||||
|
||||
# 返回0表示无违规,返回1表示有违规
|
||||
if [ $violations -gt 0 ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 5. 生成检查报告
|
||||
# ============================================================================
|
||||
generate_report() {
|
||||
local chapter="$1"
|
||||
local chapter_name=$(basename "$chapter" .txt)
|
||||
local report_file="${chapter%.txt}-检查报告.md"
|
||||
|
||||
# 如果章节在 NOVEL_DIR 下,报告也要放到 NOVEL_DIR
|
||||
if [[ "$chapter" == "$NOVEL_DIR"* ]]; then
|
||||
local base_name=$(basename "$chapter" .txt)
|
||||
report_file="$NOVEL_DIR/${base_name}-检查报告.md"
|
||||
fi
|
||||
|
||||
# 检查各项
|
||||
local format_status=0
|
||||
local length_status=0
|
||||
local desc_status=0
|
||||
local prohibited_status=0
|
||||
|
||||
check_format "$chapter" || format_status=1
|
||||
echo ""
|
||||
check_length "$chapter" || length_status=1
|
||||
echo ""
|
||||
check_description "$chapter" || desc_status=1
|
||||
echo ""
|
||||
check_prohibited "$chapter" || prohibited_status=1
|
||||
|
||||
# 计算总分
|
||||
local total=4
|
||||
local passed=$((total - format_status - length_status - desc_status - prohibited_status))
|
||||
local score=$((passed * 100 / total))
|
||||
|
||||
# 生成报告
|
||||
cat > "$report_file" << MD
|
||||
# ${chapter_name} - 格式检查报告
|
||||
|
||||
**时间**: $TIMESTAMP
|
||||
**章节**: $chapter_name
|
||||
|
||||
## 检查结果
|
||||
|
||||
| 项目 | 状态 | 分值 |
|
||||
|------|------|------|
|
||||
| 格式规范 | $([ $format_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $format_status -eq 0 ] && echo "25" || echo "0") |
|
||||
| 字数标准 | $([ $length_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $length_status -eq 0 ] && echo "25" || echo "0") |
|
||||
| 描写标准 | $([ $desc_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $desc_status -eq 0 ] && echo "25" || echo "0") |
|
||||
| 禁止项 | $([ $prohibited_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $prohibited_status -eq 0 ] && echo "25" || echo "0") |
|
||||
|
||||
**总分**: $score/100
|
||||
|
||||
$(if [ $score -ge 75 ]; then
|
||||
echo "## ✅ 检查结果: 通过"
|
||||
else
|
||||
echo "## ⚠️ 检查结果: 需要改进"
|
||||
fi)
|
||||
|
||||
## 改进建议
|
||||
|
||||
$(if [ $format_status -eq 1 ]; then
|
||||
echo "- 遵守写作标准程序,禁止Markdown标题、分隔线"
|
||||
fi)
|
||||
$(if [ $length_status -eq 1 ]; then
|
||||
echo "- 调整字数至5000-8000字范围"
|
||||
fi)
|
||||
$(if [ $desc_status -eq 1 ]; then
|
||||
echo "- 增加内心独白、动作描写、对话、环境描写"
|
||||
fi)
|
||||
$(if [ $prohibited_status -eq 1 ]; then
|
||||
echo "- 减少禁止使用的表达(沉默良久、省略号、过渡词)"
|
||||
fi)
|
||||
|
||||
---
|
||||
*自动生成于 $TIMESTAMP*
|
||||
MD
|
||||
|
||||
echo ""
|
||||
echo "📁 报告: $report_file"
|
||||
echo "📊 得分: $score/100"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 主程序
|
||||
# ============================================================================
|
||||
main() {
|
||||
echo "╔════════════════════════════════════════════════════╗"
|
||||
echo "║ 小说写作规范检查模块 v1.1 ║"
|
||||
echo "╚════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
# 检查最新章节
|
||||
local latest=$(ls -t "$NOVEL_DIR"/*.txt 2>/dev/null | grep -E "[0-9]+章" | head -1)
|
||||
|
||||
if [ -z "$latest" ]; then
|
||||
echo "ℹ️ 未发现章节文件"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📖 检查最新章节: $(basename "$latest")"
|
||||
generate_report "$latest"
|
||||
else
|
||||
echo "📖 检查章节: $1"
|
||||
generate_report "$NOVEL_DIR/$1"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ 检查完成"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in new issue
Block a user