Chart / dataset /label /Vchart /pie /fix_vchart_json.py
adddrett's picture
clean init
9fce90e
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import json
import os
import re
import sys
from pathlib import Path
def process_file(path: Path, pattern: re.Pattern, dry_run: bool, backup: bool) -> tuple[bool, str]:
"""
Return (changed, message)
"""
m = pattern.search(path.name)
if not m:
return (False, f"跳过(文件名不匹配):{path.name}")
number_str = m.group(1) # 保留前导 0,例如 "0014"
try:
text = path.read_text(encoding="utf-8")
except UnicodeDecodeError:
# 有些文件可能是 ANSI/GBK
text = path.read_text(encoding="utf-8-sig", errors="replace")
try:
data = json.loads(text)
except Exception as e:
return (False, f"错误(JSON 解析失败):{path.name} -> {e}")
if not isinstance(data, dict):
return (False, f"跳过(JSON 顶层不是对象):{path.name}")
old_number = data.get("Number", None)
old_source = data.get("Source", None)
old_source = data.get("Type", None)
data["Number"] = str(number_str) # 明确字符串
data["Source"] = "Vchart"
data["Type"] = "pie"
# 判断是否有实际变化
changed = (old_number != data["Number"]) or (old_source != data["Source"])
if dry_run:
return (changed, f"[DRY] {path.name}: Number {old_number!r} -> {data['Number']!r}, Source {old_source!r} -> 'Vchart'")
if changed and backup:
bak = path.with_suffix(path.suffix + ".bak")
if not bak.exists():
bak.write_text(text, encoding="utf-8")
if changed:
path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
return (True, f"已修改:{path.name} -> Number='{number_str}', Source='Vchart'")
else:
return (False, f"无变化:{path.name}(已是目标值)")
def iter_json_files(folder: Path, recursive: bool):
if recursive:
yield from folder.rglob("*.json")
else:
yield from folder.glob("*.json")
def main():
ap = argparse.ArgumentParser(description="批量修改 JSON: Number=文件名中的数字字符串; Source=Vchart")
ap.add_argument("dir", help="要处理的文件夹路径")
ap.add_argument("--recursive", action="store_true", help="递归处理子文件夹")
ap.add_argument("--dry-run", action="store_true", help="只打印不写入")
ap.add_argument("--backup", action="store_true", help="修改前生成 .bak(仅第一次)")
ap.add_argument("--pattern", default=r"chart_(\d+)_", help=r"从文件名提取数字的正则,默认: chart_(\d+)_")
args = ap.parse_args()
folder = Path(args.dir)
if not folder.exists() or not folder.is_dir():
print(f"目录不存在或不是文件夹:{folder}", file=sys.stderr)
return 2
pattern = re.compile(args.pattern)
total = 0
changed_count = 0
skipped_or_nochange = 0
for p in iter_json_files(folder, args.recursive):
total += 1
changed, msg = process_file(p, pattern, args.dry_run, args.backup)
print(msg)
if changed:
changed_count += 1
else:
skipped_or_nochange += 1
print("\n==== 统计 ====")
print(f"总计扫描: {total}")
print(f"发生修改: {changed_count}")
print(f"跳过/无变化/错误: {skipped_or_nochange}")
return 0
if __name__ == "__main__":
raise SystemExit(main())