vault backup: 2026-01-05 14:26:17
This commit is contained in:
@@ -0,0 +1,404 @@
|
||||
# 中文文件/目录名重命名为英文
|
||||
# 功能:
|
||||
# 1. 扫描所有中文文件和目录
|
||||
# 2. 生成英文重命名映射表
|
||||
# 3. 执行重命名
|
||||
# 4. 更新所有引用链接
|
||||
|
||||
param(
|
||||
[switch]$DryRun = $false, # 默认预览模式
|
||||
[switch]$Execute = $false, # 执行模式
|
||||
[int]$MaxLength = 50 # 文件名最大长度
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$mappingFile = ".\chinese-to-english-mapping.csv"
|
||||
|
||||
# 中文到英文的翻译字典(常用词汇)
|
||||
$translationDict = @{
|
||||
# 项目相关
|
||||
"广汽" = "GAC"
|
||||
"物联网" = "IoT"
|
||||
"AIOT" = "AIoT"
|
||||
"自动驾驶" = "Autonomous-Driving"
|
||||
"从化应急" = "Conghua-Emergency"
|
||||
"公文交换" = "Document-Exchange"
|
||||
"商务局" = "Commerce-Bureau"
|
||||
"市发改委" = "Municipal-Development-Reform"
|
||||
"虚拟数据中心" = "Virtual-Data-Center"
|
||||
"增城区" = "Zengcheng-District"
|
||||
"番禺区" = "Panyu-District"
|
||||
"工信" = "Industry-Info"
|
||||
"道路秩序" = "Road-Order"
|
||||
"南电" = "CSG" # China Southern Grid
|
||||
"南方电网" = "China-Southern-Grid"
|
||||
|
||||
# 文件夹名称
|
||||
"城中村" = "Urban-Village"
|
||||
"番禺城中村" = "Panyu-Urban-Village"
|
||||
"番禺公文" = "Panyu-Document"
|
||||
"番禺信用" = "Panyu-Credit"
|
||||
"番禺住建" = "Panyu-Housing"
|
||||
"公文" = "Document"
|
||||
"信用" = "Credit"
|
||||
"住建" = "Housing"
|
||||
"增城区信息化项目管理系统" = "Zengcheng-IT-Project-Mgmt"
|
||||
|
||||
# 文件名关键词
|
||||
"培训记录整理" = "Training-Records"
|
||||
"设备添加" = "Device-Addition"
|
||||
"测试环境" = "Test-Environment"
|
||||
"维护" = "Maintenance"
|
||||
"数据流向" = "Data-Flow"
|
||||
"系统架构" = "System-Architecture"
|
||||
"登陆" = "Login"
|
||||
"配置" = "Configuration"
|
||||
"问题处理" = "Issue-Handling"
|
||||
"处理" = "Handling"
|
||||
"升级" = "Upgrade"
|
||||
"漏洞处理" = "Vulnerability-Fix"
|
||||
"达梦" = "DM-Database"
|
||||
"等保问题描述" = "Security-Issues"
|
||||
"等保修复" = "Security-Fixes"
|
||||
"基线" = "Baseline"
|
||||
"重建主节点" = "Rebuild-Master-Node"
|
||||
"设备电源" = "Device-Power"
|
||||
"智谱清言" = "ChatGLM"
|
||||
"热点升级" = "Hotspot-Upgrade"
|
||||
"自行车" = "Bicycle"
|
||||
"酸黄瓜制作" = "Pickled-Cucumber-Recipe"
|
||||
"酸黄瓜" = "Pickled-Cucumber"
|
||||
"文明" = "Civilization"
|
||||
"摩托罗拉" = "Motorola"
|
||||
"产出" = "Deliverables"
|
||||
"架构目标" = "Architecture-Goals"
|
||||
"决策方法" = "Decision-Methods"
|
||||
"系统架构分析员知识体系" = "SA-Knowledge-System"
|
||||
"芹菜炒牛肉" = "Celery-Beef-Stir-Fry"
|
||||
"图片生成提示词模板" = "Image-Prompt-Template"
|
||||
|
||||
# 通用词汇
|
||||
"机场推荐" = "VPN-Airport-Recommendations"
|
||||
"软件供应商手册" = "Software-Vendor-Handbook"
|
||||
"生成和提供" = "Generation-and-Provision"
|
||||
"解读" = "Interpretation"
|
||||
"关于" = "About"
|
||||
"软件物料清单" = "Software-Bill-of-Materials"
|
||||
"你所需要了解的一切" = "Everything-You-Need-to-Know"
|
||||
"如何使用" = "How-to-Use"
|
||||
"微软的开源工具生成" = "Microsoft-OpenSource-Tools"
|
||||
"如何通过" = "How-to-Achieve"
|
||||
"实现安全治理" = "Security-Governance"
|
||||
"联想移动互联及数字家庭产品服务支持" = "Lenovo-Mobile-Digital-Home-Support"
|
||||
"需要考虑的" = "Top"
|
||||
"种顶级" = ""
|
||||
"工具" = "Tools"
|
||||
"中文网" = "CN"
|
||||
"如何购买" = "How-to-Purchase"
|
||||
"分钟搞定" = "Quick-Guide"
|
||||
"功能强大" = "Powerful"
|
||||
"开源项目" = "Open-Source-Project"
|
||||
"创造令人愉悦的身份体验" = "Delightful-Identity-Experience"
|
||||
"深度学习雾计算平台" = "Deep-Learning-Fog-Platform"
|
||||
"开户教程" = "Account-Opening-Guide"
|
||||
"一张数据量很大的表" = "Large-Data-Table"
|
||||
"分页查询特别耗时" = "Slow-Pagination-Query"
|
||||
"你有什么优化方案" = "Optimization-Solutions"
|
||||
"实现" = "Implementation"
|
||||
"拨号与" = "Dialing-and"
|
||||
"机场评测" = "VPN-Reviews"
|
||||
"订阅" = "Subscription"
|
||||
"报文简介" = "Message-Intro"
|
||||
"博客" = "Blog"
|
||||
"国内镜像源列表" = "China-Mirror-List"
|
||||
"年" = ""
|
||||
"月" = ""
|
||||
"日" = ""
|
||||
"亲测可用" = "Tested-Working"
|
||||
"安装" = "Installation"
|
||||
"技术文档" = "Technical-Docs"
|
||||
"数据库" = "Database"
|
||||
"博客园" = "cnblogs"
|
||||
"安装前准备" = "Pre-Installation"
|
||||
"配置实例" = "Configure-Instance"
|
||||
"离线安装" = "Offline-Installation"
|
||||
"数据库安装" = "DB-Installation"
|
||||
"技术我的一些" = "My"
|
||||
"学习经验" = "Learning-Experience"
|
||||
"安装和打包" = "Installation-and-Packaging"
|
||||
"权限校验" = "Permission-Validation"
|
||||
"官网" = "Official-Site"
|
||||
"学习笔记" = "Learning-Notes"
|
||||
"应用" = "Application"
|
||||
"部署" = "Deployment"
|
||||
"单实例数据库" = "Single-Instance-DB"
|
||||
"一个" = "A"
|
||||
"的工作学习笔记" = "Work-Study-Notes"
|
||||
"集成" = "Integration"
|
||||
"节点访问局域网服务器的配置方法" = "LAN-Server-Access-Config"
|
||||
"公开镜像仓库未授权访问" = "Public-Registry-Unauthorized-Access"
|
||||
"数据库从" = "DB-Migration-from"
|
||||
"迁移到" = "to"
|
||||
"综合讨论区" = "Discussion"
|
||||
"智能家居技术论坛" = "Smart-Home-Forum"
|
||||
"树莓派" = "Raspberry-Pi"
|
||||
"边界路由器配置" = "Border-Router-Config"
|
||||
"配置" = "Config"
|
||||
"雾凇拼音" = "Rime-Ice"
|
||||
"长期维护的简体词库" = "Simplified-Chinese-Dict"
|
||||
"中国申请" = "China-Application"
|
||||
"中国区免费" = "China-Free"
|
||||
"使用攻略" = "Usage-Guide"
|
||||
"云" = "Cloud"
|
||||
"详细" = "Detailed"
|
||||
"注册申请图文教程" = "Registration-Tutorial"
|
||||
"整合" = "Integration"
|
||||
"软件开发实施" = "Software-Implementation"
|
||||
"服装生鲜家具外贸供应链开源" = "Apparel-Food-Furniture-Supply-Chain"
|
||||
"专业实施" = "Pro-Implementation"
|
||||
"什麼是" = "What-is"
|
||||
"軟體物料清單" = "SBOM"
|
||||
"網路安全解決方案" = "Network-Security-Solutions"
|
||||
"作为旁路网关" = "as-Bypass-Gateway"
|
||||
"不是旁路由" = "not-Bypass-Router"
|
||||
"单臂路由" = "One-Armed-Router"
|
||||
"的终极设置方法" = "Ultimate-Setup"
|
||||
"破解迷思" = "Debunking-Myths"
|
||||
"少数派" = "sspai"
|
||||
"知乎" = "Zhihu"
|
||||
"掘金" = "Juejin"
|
||||
}
|
||||
|
||||
# 拼音转换函数(简化版,使用首字母)
|
||||
function Get-Pinyin {
|
||||
param([string]$Text)
|
||||
|
||||
# 先尝试从字典查找
|
||||
if ($translationDict.ContainsKey($Text)) {
|
||||
return $translationDict[$Text]
|
||||
}
|
||||
|
||||
# 检查是否有部分匹配
|
||||
foreach ($key in $translationDict.Keys) {
|
||||
if ($Text.Contains($key)) {
|
||||
$Text = $Text.Replace($key, $translationDict[$key])
|
||||
}
|
||||
}
|
||||
|
||||
# 如果还有中文,返回原文(后续手动处理)
|
||||
if ($Text -match '[\u4e00-\u9fa5]') {
|
||||
# 简单清理:移除特殊字符
|
||||
$Text = $Text -replace '[:。,、;!?""''()【】《》\s]+', '-'
|
||||
$Text = $Text -replace '^-+|-+$', ''
|
||||
}
|
||||
|
||||
return $Text
|
||||
}
|
||||
|
||||
# 规范化文件名(移除非法字符,控制长度)
|
||||
function Normalize-FileName {
|
||||
param([string]$Name, [string]$Extension = "")
|
||||
|
||||
# 移除或替换非法字符
|
||||
$Name = $Name -replace '[<>:"/\\|?*]', '-'
|
||||
$Name = $Name -replace '\s+', '-'
|
||||
$Name = $Name -replace '-+', '-'
|
||||
$Name = $Name -replace '^-+|-+$', ''
|
||||
|
||||
# 控制长度
|
||||
if ($Name.Length -gt $MaxLength) {
|
||||
$Name = $Name.Substring(0, $MaxLength)
|
||||
$Name = $Name -replace '-+$', ''
|
||||
}
|
||||
|
||||
if ($Extension) {
|
||||
return "$Name$Extension"
|
||||
}
|
||||
return $Name
|
||||
}
|
||||
|
||||
Write-Host "=== 中文文件名重命名工具 ===" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
if ($Execute) {
|
||||
Write-Host "⚠️ 执行模式:将真实重命名文件并更新链接" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "👁️ 预览模式:仅生成映射表,不执行重命名" -ForegroundColor Green
|
||||
Write-Host " 使用 -Execute 参数执行真实重命名" -ForegroundColor Gray
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# 1. 扫描所有中文文件和目录
|
||||
Write-Host "📁 扫描中文文件和目录..." -ForegroundColor Cyan
|
||||
|
||||
$chineseFiles = Get-ChildItem -Recurse -File | Where-Object { $_.Name -match '[\u4e00-\u9fa5]' }
|
||||
$chineseDirs = Get-ChildItem -Recurse -Directory | Where-Object { $_.Name -match '[\u4e00-\u9fa5]' } | Sort-Object FullName -Descending
|
||||
|
||||
Write-Host " 找到 $($chineseFiles.Count) 个中文文件" -ForegroundColor White
|
||||
Write-Host " 找到 $($chineseDirs.Count) 个中文目录" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
# 2. 生成重命名映射
|
||||
Write-Host "📝 生成重命名映射..." -ForegroundColor Cyan
|
||||
|
||||
$mappings = @()
|
||||
|
||||
# 处理目录(从深层到浅层,避免父目录先改名导致路径失效)
|
||||
foreach ($dir in $chineseDirs) {
|
||||
$oldName = $dir.Name
|
||||
$newName = Get-Pinyin -Text $oldName
|
||||
$newName = Normalize-FileName -Name $newName
|
||||
|
||||
$relPath = $dir.FullName.Replace((Get-Location).Path, ".").Replace("\", "/")
|
||||
$parentPath = Split-Path $relPath -Parent
|
||||
$newPath = Join-Path $parentPath $newName
|
||||
|
||||
$mappings += [PSCustomObject]@{
|
||||
Type = "Directory"
|
||||
OldPath = $relPath
|
||||
NewPath = $newPath
|
||||
OldName = $oldName
|
||||
NewName = $newName
|
||||
}
|
||||
}
|
||||
|
||||
# 处理文件
|
||||
foreach ($file in $chineseFiles) {
|
||||
$oldName = $file.BaseName
|
||||
$extension = $file.Extension
|
||||
$newName = Get-Pinyin -Text $oldName
|
||||
$newName = Normalize-FileName -Name $newName -Extension $extension
|
||||
|
||||
$relPath = $file.FullName.Replace((Get-Location).Path, ".").Replace("\", "/")
|
||||
$parentPath = Split-Path $relPath -Parent
|
||||
$newPath = Join-Path $parentPath $newName
|
||||
|
||||
$mappings += [PSCustomObject]@{
|
||||
Type = "File"
|
||||
OldPath = $relPath
|
||||
NewPath = $newPath
|
||||
OldName = $file.Name
|
||||
NewName = $newName
|
||||
}
|
||||
}
|
||||
|
||||
# 保存映射表
|
||||
$mappings | Export-Csv -Path $mappingFile -Encoding UTF8 -NoTypeInformation
|
||||
Write-Host " ✅ 映射表已保存到: $mappingFile" -ForegroundColor Green
|
||||
Write-Host " 📊 总计 $($mappings.Count) 个重命名任务" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
# 3. 显示预览
|
||||
Write-Host "📋 重命名预览 (前20项):" -ForegroundColor Cyan
|
||||
$mappings | Select-Object -First 20 Type, OldName, NewName | Format-Table -AutoSize
|
||||
|
||||
if ($mappings.Count -gt 20) {
|
||||
Write-Host " ... 还有 $($mappings.Count - 20) 项(查看完整列表: $mappingFile)" -ForegroundColor Gray
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# 4. 执行重命名(仅在 -Execute 模式)
|
||||
if ($Execute) {
|
||||
Write-Host "🔄 开始执行重命名..." -ForegroundColor Yellow
|
||||
|
||||
$renamed = 0
|
||||
$failed = 0
|
||||
|
||||
# 先重命名目录
|
||||
foreach ($mapping in ($mappings | Where-Object { $_.Type -eq "Directory" })) {
|
||||
try {
|
||||
$oldPath = $mapping.OldPath -replace '^\./', ''
|
||||
$newPath = $mapping.NewPath -replace '^\./', ''
|
||||
|
||||
if (Test-Path $oldPath) {
|
||||
Rename-Item -Path $oldPath -NewName (Split-Path $newPath -Leaf) -ErrorAction Stop
|
||||
Write-Host " ✅ 目录: $($mapping.OldName) → $($mapping.NewName)" -ForegroundColor Green
|
||||
$renamed++
|
||||
}
|
||||
} catch {
|
||||
Write-Host " ❌ 失败: $($mapping.OldPath) - $_" -ForegroundColor Red
|
||||
$failed++
|
||||
}
|
||||
}
|
||||
|
||||
# 再重命名文件
|
||||
foreach ($mapping in ($mappings | Where-Object { $_.Type -eq "File" })) {
|
||||
try {
|
||||
# 更新路径(因为目录可能已改名)
|
||||
$oldPath = $mapping.OldPath -replace '^\./', ''
|
||||
|
||||
# 检查文件是否存在(路径可能因目录改名而变化)
|
||||
if (-not (Test-Path $oldPath)) {
|
||||
# 尝试查找文件
|
||||
$fileName = Split-Path $oldPath -Leaf
|
||||
$foundFiles = Get-ChildItem -Recurse -File -Filter $fileName
|
||||
if ($foundFiles.Count -eq 1) {
|
||||
$oldPath = $foundFiles[0].FullName.Replace((Get-Location).Path + "\", "")
|
||||
} else {
|
||||
throw "文件未找到或有重复"
|
||||
}
|
||||
}
|
||||
|
||||
Rename-Item -Path $oldPath -NewName $mapping.NewName -ErrorAction Stop
|
||||
Write-Host " ✅ 文件: $($mapping.OldName) → $($mapping.NewName)" -ForegroundColor Green
|
||||
$renamed++
|
||||
} catch {
|
||||
Write-Host " ❌ 失败: $($mapping.OldPath) - $_" -ForegroundColor Red
|
||||
$failed++
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "📊 重命名完成!" -ForegroundColor Cyan
|
||||
Write-Host " 成功: $renamed" -ForegroundColor Green
|
||||
Write-Host " 失败: $failed" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
|
||||
# 5. 更新链接
|
||||
Write-Host "🔗 更新 Markdown 文件中的链接..." -ForegroundColor Cyan
|
||||
|
||||
$mdFiles = Get-ChildItem -Recurse -Filter "*.md" -File
|
||||
$updatedFiles = 0
|
||||
|
||||
foreach ($mdFile in $mdFiles) {
|
||||
$content = Get-Content $mdFile.FullName -Raw -Encoding UTF8
|
||||
$originalContent = $content
|
||||
$changed = $false
|
||||
|
||||
# 更新 Wiki 链接 [[中文名]]
|
||||
foreach ($mapping in $mappings) {
|
||||
$oldBaseName = [System.IO.Path]::GetFileNameWithoutExtension($mapping.OldName)
|
||||
$newBaseName = [System.IO.Path]::GetFileNameWithoutExtension($mapping.NewName)
|
||||
|
||||
if ($content -match "\[\[$oldBaseName\]\]") {
|
||||
$content = $content -replace "\[\[$oldBaseName\]\]", "[[$newBaseName]]"
|
||||
$changed = $true
|
||||
}
|
||||
|
||||
# 更新路径引用
|
||||
$oldPathPattern = [regex]::Escape($mapping.OldPath -replace '^\./', '')
|
||||
if ($content -match $oldPathPattern) {
|
||||
$newPathEscaped = $mapping.NewPath -replace '^\./', ''
|
||||
$content = $content -replace $oldPathPattern, $newPathEscaped
|
||||
$changed = $true
|
||||
}
|
||||
}
|
||||
|
||||
if ($changed) {
|
||||
Set-Content -Path $mdFile.FullName -Value $content -Encoding UTF8 -NoNewline
|
||||
$updatedFiles++
|
||||
Write-Host " ✅ 更新: $($mdFile.FullName.Replace((Get-Location).Path, '.'))" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "📊 链接更新完成!更新了 $updatedFiles 个文件" -ForegroundColor Green
|
||||
|
||||
} else {
|
||||
Write-Host "💡 下一步:" -ForegroundColor Yellow
|
||||
Write-Host " 1. 查看映射表: $mappingFile" -ForegroundColor White
|
||||
Write-Host " 2. 确认无误后,运行: .\.scripts\rename-chinese-to-english.ps1 -Execute" -ForegroundColor White
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "✨ 完成!" -ForegroundColor Cyan
|
||||
@@ -0,0 +1,408 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
中文文件/目录名重命名为英文
|
||||
|
||||
功能:
|
||||
1. 扫描所有中文文件和目录
|
||||
2. 生成英文重命名映射表
|
||||
3. 执行重命名
|
||||
4. 更新所有引用链接
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import csv
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Tuple
|
||||
|
||||
# 中文到英文的翻译字典
|
||||
TRANSLATION_DICT = {
|
||||
# 项目相关
|
||||
"广汽": "GAC",
|
||||
"物联网AIOT": "AIoT",
|
||||
"物联网": "IoT",
|
||||
"AIOT": "AIoT",
|
||||
"自动驾驶": "Autonomous-Driving",
|
||||
"从化应急": "Conghua-Emergency",
|
||||
"公文交换": "Document-Exchange",
|
||||
"商务局": "Commerce-Bureau",
|
||||
"市发改委": "Municipal-Development-Reform",
|
||||
"虚拟数据中心": "Virtual-Data-Center",
|
||||
"增城区": "Zengcheng-District",
|
||||
"番禺区": "Panyu-District",
|
||||
"工信": "Industry-Info",
|
||||
"道路秩序": "Road-Order",
|
||||
"南电": "CSG",
|
||||
"南方电网": "China-Southern-Grid",
|
||||
|
||||
# 文件夹名称
|
||||
"城中村": "Urban-Village",
|
||||
"番禺城中村": "Panyu-Urban-Village",
|
||||
"番禺公文": "Panyu-Document",
|
||||
"番禺信用": "Panyu-Credit",
|
||||
"番禺住建": "Panyu-Housing",
|
||||
"公文": "Document",
|
||||
"信用": "Credit",
|
||||
"住建": "Housing",
|
||||
"增城区信息化项目管理系统": "Zengcheng-IT-Project-Mgmt",
|
||||
|
||||
# 文件名关键词
|
||||
"不明确的问题": "Unclear-Issues",
|
||||
"培训记录整理": "Training-Records",
|
||||
"设备添加": "Device-Addition",
|
||||
"测试环境": "Test-Environment",
|
||||
"维护": "Maintenance",
|
||||
"数据流向": "Data-Flow",
|
||||
"系统架构": "System-Architecture",
|
||||
"登陆": "Login",
|
||||
"配置": "Configuration",
|
||||
"问题处理": "Issue-Handling",
|
||||
"处理": "Handling",
|
||||
"升级": "Upgrade",
|
||||
"漏洞处理": "Vulnerability-Fix",
|
||||
"达梦": "DM-Database",
|
||||
"等保问题描述": "Security-Issues",
|
||||
"等保修复": "Security-Fixes",
|
||||
"基线": "Baseline",
|
||||
"重建主节点": "Rebuild-Master-Node",
|
||||
"设备电源": "Device-Power",
|
||||
"智谱清言": "ChatGLM",
|
||||
"热点升级": "Hotspot-Upgrade",
|
||||
"自行车": "Bicycle",
|
||||
"酸黄瓜制作": "Pickled-Cucumber-Recipe",
|
||||
"酸黄瓜": "Pickled-Cucumber",
|
||||
"文明": "Civilization",
|
||||
"摩托罗拉": "Motorola",
|
||||
"产出": "Deliverables",
|
||||
"架构目标": "Architecture-Goals",
|
||||
"决策方法": "Decision-Methods",
|
||||
"系统架构分析员知识体系": "SA-Knowledge-System",
|
||||
"芹菜炒牛肉": "Celery-Beef-Stir-Fry",
|
||||
"图片生成提示词模板": "Image-Prompt-Template",
|
||||
"在非原生ESIM设备上申请Giffgaff ESIM": "Apply-Giffgaff-ESIM-on-Non-Native-Device",
|
||||
|
||||
# 网页剪藏常用词
|
||||
"联想移动互联及数字家庭产品服务支持": "Lenovo-Support",
|
||||
"节点访问局域网服务器的配置方法": "LAN-Server-Access-Config",
|
||||
"边界路由器配置": "Border-Router-Config",
|
||||
"树莓派": "Raspberry-Pi",
|
||||
"机场推荐": "VPN-Recommendations",
|
||||
"机场评测": "VPN-Reviews",
|
||||
"软件供应商手册": "Software-Vendor-Handbook",
|
||||
"解读": "Interpretation",
|
||||
"关于": "About",
|
||||
"软件物料清单": "SBOM",
|
||||
"如何": "How-to",
|
||||
"教程": "Tutorial",
|
||||
"博客": "Blog",
|
||||
"技术文档": "Technical-Docs",
|
||||
"学习笔记": "Learning-Notes",
|
||||
"使用攻略": "Guide",
|
||||
"安装": "Installation",
|
||||
"配置": "Config",
|
||||
"实现": "Implementation",
|
||||
"什麼是": "What-is",
|
||||
"軟體物料清單": "SBOM",
|
||||
"網路安全解決方案": "Network-Security",
|
||||
"艾索科技": "AISEC",
|
||||
"作为旁路网关": "Bypass-Gateway",
|
||||
"不是旁路由": "",
|
||||
"单臂路由": "",
|
||||
"的终极设置方法": "Ultimate-Setup",
|
||||
"破解迷思": "Debunking-Myths",
|
||||
"少数派": "sspai",
|
||||
"麒麟": "Kylin",
|
||||
"离线安装": "Offline-Installation",
|
||||
"报文简介": "Message-Intro",
|
||||
"公开镜像仓库未授权访问": "Public-Registry-Unauth",
|
||||
"数据库从": "DB-Migration-from",
|
||||
"迁移到": "to",
|
||||
"综合讨论区": "Discussion",
|
||||
"瀚思彼岸": "HASSBIAN",
|
||||
"智能家居技术论坛": "Smart-Home-Forum",
|
||||
"雾凇拼音": "Rime-Ice",
|
||||
"长期维护的简体词库": "Simplified-Dict",
|
||||
"中国申请": "China-Application",
|
||||
"中国区免费": "China-Free",
|
||||
"年使用攻略": "Year-Guide",
|
||||
"云": "Cloud",
|
||||
"详细": "Detailed",
|
||||
"注册申请图文教程": "Registration-Tutorial",
|
||||
"整合": "Integration",
|
||||
"软件开发实施": "Software-Dev",
|
||||
"广州尚鹏": "Guangzhou-SP",
|
||||
"服装生鲜家具外贸供应链开源": "Supply-Chain",
|
||||
"专业实施": "Pro-Impl",
|
||||
"学习经验": "Learning-Experience",
|
||||
"安装和打包": "Installation-Packaging",
|
||||
"权限校验": "Permission-Validation",
|
||||
"官网": "Official",
|
||||
"学习笔记": "Learning-Notes",
|
||||
"应用": "Application",
|
||||
"部署": "Deployment",
|
||||
"单实例数据库": "Single-Instance-DB",
|
||||
"的工作学习笔记": "Work-Notes",
|
||||
"集成": "Integration",
|
||||
"国内镜像源列表": "China-Mirror-List",
|
||||
"亲测可用": "Tested",
|
||||
"技术文档": "Tech-Docs",
|
||||
"安装前准备": "Pre-Installation",
|
||||
"配置实例": "Config-Instance",
|
||||
"数据库安装": "DB-Installation",
|
||||
"技术我的一些": "My",
|
||||
}
|
||||
|
||||
|
||||
def has_chinese(text: str) -> bool:
|
||||
"""检查文本是否包含中文"""
|
||||
return bool(re.search(r'[\u4e00-\u9fa5]', text))
|
||||
|
||||
|
||||
def translate_chinese(text: str, max_length: int = 50) -> str:
|
||||
"""将中文翻译为英文"""
|
||||
result = text
|
||||
|
||||
# 按长度排序,优先匹配长词组
|
||||
sorted_dict = sorted(TRANSLATION_DICT.items(), key=lambda x: len(x[0]), reverse=True)
|
||||
|
||||
for chinese, english in sorted_dict:
|
||||
result = result.replace(chinese, english)
|
||||
|
||||
# 移除剩余的中文(如果翻译不完整,保留拼音或删除)
|
||||
result = re.sub(r'[\u4e00-\u9fa5]+', '-', result)
|
||||
|
||||
# 清理特殊字符
|
||||
result = re.sub(r'[\u3000-\u303f\uff00-\uffef\s]+', '-', result)
|
||||
result = re.sub(r'[<>:"/\\|?*]+', '-', result)
|
||||
result = re.sub(r'-+', '-', result)
|
||||
result = result.strip('-')
|
||||
|
||||
# 控制长度
|
||||
if len(result) > max_length:
|
||||
result = result[:max_length].rstrip('-')
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def scan_chinese_files_and_dirs(root_dir: Path) -> Tuple[List[Path], List[Path]]:
|
||||
"""扫描所有包含中文的文件和目录"""
|
||||
chinese_files = []
|
||||
chinese_dirs = []
|
||||
|
||||
# 排除的目录
|
||||
exclude_dirs = {'.git', '.obsidian', '.smart-env', 'node_modules'}
|
||||
|
||||
for item in root_dir.rglob('*'):
|
||||
# 跳过排除的目录
|
||||
if any(excl in item.parts for excl in exclude_dirs):
|
||||
continue
|
||||
|
||||
if has_chinese(item.name):
|
||||
if item.is_file():
|
||||
chinese_files.append(item)
|
||||
elif item.is_dir():
|
||||
chinese_dirs.append(item)
|
||||
|
||||
# 目录按深度排序(深的在前,避免父目录先改名)
|
||||
chinese_dirs.sort(key=lambda p: len(p.parts), reverse=True)
|
||||
|
||||
return chinese_files, chinese_dirs
|
||||
|
||||
|
||||
def generate_mappings(files: List[Path], dirs: List[Path], root_dir: Path, max_length: int = 50) -> List[Dict]:
|
||||
"""生成重命名映射"""
|
||||
mappings = []
|
||||
|
||||
# 处理目录
|
||||
for dir_path in dirs:
|
||||
old_name = dir_path.name
|
||||
new_name = translate_chinese(old_name, max_length)
|
||||
|
||||
rel_path = dir_path.relative_to(root_dir)
|
||||
new_path = dir_path.parent / new_name
|
||||
new_rel_path = new_path.relative_to(root_dir)
|
||||
|
||||
mappings.append({
|
||||
'type': 'Directory',
|
||||
'old_path': str(rel_path),
|
||||
'new_path': str(new_rel_path),
|
||||
'old_name': old_name,
|
||||
'new_name': new_name,
|
||||
'abs_old_path': str(dir_path),
|
||||
'abs_new_path': str(new_path)
|
||||
})
|
||||
|
||||
# 处理文件
|
||||
for file_path in files:
|
||||
old_name = file_path.name
|
||||
stem = file_path.stem
|
||||
suffix = file_path.suffix
|
||||
|
||||
new_stem = translate_chinese(stem, max_length - len(suffix))
|
||||
new_name = new_stem + suffix
|
||||
|
||||
rel_path = file_path.relative_to(root_dir)
|
||||
new_path = file_path.parent / new_name
|
||||
new_rel_path = new_path.relative_to(root_dir)
|
||||
|
||||
mappings.append({
|
||||
'type': 'File',
|
||||
'old_path': str(rel_path),
|
||||
'new_path': str(new_rel_path),
|
||||
'old_name': old_name,
|
||||
'new_name': new_name,
|
||||
'abs_old_path': str(file_path),
|
||||
'abs_new_path': str(new_path)
|
||||
})
|
||||
|
||||
return mappings
|
||||
|
||||
|
||||
def save_mappings(mappings: List[Dict], output_file: Path):
|
||||
"""保存映射表到CSV"""
|
||||
with open(output_file, 'w', encoding='utf-8', newline='') as f:
|
||||
writer = csv.DictWriter(f, fieldnames=['type', 'old_path', 'new_path', 'old_name', 'new_name'])
|
||||
writer.writeheader()
|
||||
for mapping in mappings:
|
||||
writer.writerow({
|
||||
'type': mapping['type'],
|
||||
'old_path': mapping['old_path'],
|
||||
'new_path': mapping['new_path'],
|
||||
'old_name': mapping['old_name'],
|
||||
'new_name': mapping['new_name']
|
||||
})
|
||||
|
||||
|
||||
def execute_rename(mappings: List[Dict]) -> Tuple[int, int]:
|
||||
"""执行重命名"""
|
||||
renamed = 0
|
||||
failed = 0
|
||||
|
||||
for mapping in mappings:
|
||||
try:
|
||||
old_path = Path(mapping['abs_old_path'])
|
||||
new_path = Path(mapping['abs_new_path'])
|
||||
|
||||
if old_path.exists():
|
||||
old_path.rename(new_path)
|
||||
print(f"[+] {mapping['type']}: {mapping['old_name']} -> {mapping['new_name']}")
|
||||
renamed += 1
|
||||
else:
|
||||
print(f"[!] Skip (not exist): {mapping['old_path']}")
|
||||
except Exception as e:
|
||||
print(f"[-] Failed: {mapping['old_path']} - {e}")
|
||||
failed += 1
|
||||
|
||||
return renamed, failed
|
||||
|
||||
|
||||
def update_markdown_links(root_dir: Path, mappings: List[Dict]) -> int:
|
||||
"""更新 Markdown 文件中的链接"""
|
||||
updated_count = 0
|
||||
md_files = list(root_dir.rglob('*.md'))
|
||||
|
||||
# 排除某些目录
|
||||
exclude_dirs = {'.git', '.obsidian', '.smart-env'}
|
||||
md_files = [f for f in md_files if not any(excl in f.parts for excl in exclude_dirs)]
|
||||
|
||||
for md_file in md_files:
|
||||
try:
|
||||
content = md_file.read_text(encoding='utf-8')
|
||||
original_content = content
|
||||
|
||||
# 更新 Wiki 链接 [[中文名]]
|
||||
for mapping in mappings:
|
||||
if mapping['type'] == 'File':
|
||||
old_stem = Path(mapping['old_name']).stem
|
||||
new_stem = Path(mapping['new_name']).stem
|
||||
|
||||
# Wiki 链接
|
||||
content = re.sub(
|
||||
rf'\[\[{re.escape(old_stem)}\]\]',
|
||||
f'[[{new_stem}]]',
|
||||
content
|
||||
)
|
||||
|
||||
# 相对路径链接
|
||||
old_path_escaped = re.escape(mapping['old_path'].replace('\\', '/'))
|
||||
new_path_fixed = mapping['new_path'].replace('\\', '/')
|
||||
content = re.sub(old_path_escaped, new_path_fixed, content)
|
||||
|
||||
if content != original_content:
|
||||
md_file.write_text(content, encoding='utf-8')
|
||||
rel_path = md_file.relative_to(root_dir)
|
||||
print(f"[+] Updated: {rel_path}")
|
||||
updated_count += 1
|
||||
|
||||
except Exception as e:
|
||||
print(f"[-] Update failed: {md_file} - {e}")
|
||||
|
||||
return updated_count
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='中文文件名重命名为英文')
|
||||
parser.add_argument('--execute', action='store_true', help='执行重命名(默认为预览模式)')
|
||||
parser.add_argument('--max-length', type=int, default=50, help='文件名最大长度(默认50)')
|
||||
args = parser.parse_args()
|
||||
|
||||
root_dir = Path.cwd()
|
||||
mapping_file = root_dir / 'chinese-to-english-mapping.csv'
|
||||
|
||||
print("=== Chinese to English Rename Tool ===\n")
|
||||
|
||||
if args.execute:
|
||||
print("[!] EXECUTE MODE: Will rename files and update links")
|
||||
else:
|
||||
print("[i] PREVIEW MODE: Generate mapping only, no actual rename")
|
||||
print(" Use --execute to perform actual rename")
|
||||
print()
|
||||
|
||||
# Scan
|
||||
print("[*] Scanning Chinese files and directories...")
|
||||
chinese_files, chinese_dirs = scan_chinese_files_and_dirs(root_dir)
|
||||
print(f" Found {len(chinese_files)} Chinese files")
|
||||
print(f" Found {len(chinese_dirs)} Chinese directories\n")
|
||||
|
||||
# Generate mappings
|
||||
print("[*] Generating rename mappings...")
|
||||
mappings = generate_mappings(chinese_files, chinese_dirs, root_dir, args.max_length)
|
||||
save_mappings(mappings, mapping_file)
|
||||
print(f" [+] Mapping saved to: {mapping_file}")
|
||||
print(f" [+] Total {len(mappings)} rename tasks\n")
|
||||
|
||||
# Preview
|
||||
print("[*] Rename Preview (first 20):")
|
||||
print(f"{'Type':<10} {'Old Name':<40} {'New Name':<40}")
|
||||
print("-" * 90)
|
||||
for mapping in mappings[:20]:
|
||||
print(f"{mapping['type']:<10} {mapping['old_name']:<40} {mapping['new_name']:<40}")
|
||||
|
||||
if len(mappings) > 20:
|
||||
print(f"\n ... and {len(mappings) - 20} more (see full list: {mapping_file})")
|
||||
print()
|
||||
|
||||
# Execute rename
|
||||
if args.execute:
|
||||
print("[*] Starting rename...")
|
||||
renamed, failed = execute_rename(mappings)
|
||||
print(f"\n[*] Rename complete!")
|
||||
print(f" Success: {renamed}")
|
||||
print(f" Failed: {failed}\n")
|
||||
|
||||
# Update links
|
||||
print("[*] Updating Markdown links...")
|
||||
updated_count = update_markdown_links(root_dir, mappings)
|
||||
print(f"\n[*] Link update complete! Updated {updated_count} files\n")
|
||||
else:
|
||||
print("[i] Next steps:")
|
||||
print(f" 1. Review mapping: {mapping_file}")
|
||||
print(f" 2. If OK, run: python .scripts/rename-chinese-to-english.py --execute\n")
|
||||
|
||||
print("[+] Done!")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,160 @@
|
||||
# Vault-Para 结构扫描脚本
|
||||
# 用法: 在 my-vault 目录中运行此脚本
|
||||
# 输出: 在当前目录生成 vault-para-scan-report.md
|
||||
|
||||
$vaultParaPath = "D:\tmp\vault\vault-para"
|
||||
$reportPath = ".\vault-para-scan-report.md"
|
||||
|
||||
Write-Host "正在扫描 vault-para 结构..." -ForegroundColor Green
|
||||
Write-Host "目标路径: $vaultParaPath" -ForegroundColor Cyan
|
||||
|
||||
# 检查路径是否存在
|
||||
if (-not (Test-Path $vaultParaPath)) {
|
||||
Write-Host "❌ 错误: 找不到 vault-para 目录: $vaultParaPath" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Push-Location $vaultParaPath
|
||||
|
||||
# 初始化报告
|
||||
$report = @"
|
||||
# Vault-Para 扫描报告
|
||||
扫描时间: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
||||
扫描路径: $vaultParaPath
|
||||
|
||||
---
|
||||
|
||||
## 📊 统计概览
|
||||
|
||||
"@
|
||||
|
||||
# 统计信息
|
||||
$mdFiles = Get-ChildItem -Recurse -Filter "*.md" -File
|
||||
$allFiles = Get-ChildItem -Recurse -File
|
||||
$directories = Get-ChildItem -Recurse -Directory
|
||||
|
||||
$report += @"
|
||||
- **Markdown 文件**: $($mdFiles.Count)
|
||||
- **总文件数**: $($allFiles.Count)
|
||||
- **目录数**: $($directories.Count)
|
||||
|
||||
"@
|
||||
|
||||
# 文件类型统计
|
||||
$report += "`n## 📁 文件类型分布`n`n"
|
||||
$fileTypes = $allFiles | Group-Object Extension | Sort-Object Count -Descending | Select-Object -First 10
|
||||
$report += "| 扩展名 | 数量 |`n"
|
||||
$report += "|--------|------|`n"
|
||||
foreach ($type in $fileTypes) {
|
||||
$ext = if ($type.Name) { $type.Name } else { "(无扩展名)" }
|
||||
$report += "| $ext | $($type.Count) |`n"
|
||||
}
|
||||
|
||||
# 目录结构(完整树形)
|
||||
$report += "`n## 🌳 完整目录结构`n`n"
|
||||
$report += "``````text`n"
|
||||
|
||||
function Get-TreeStructure {
|
||||
param($Path, $Prefix = "", $IsLast = $true)
|
||||
|
||||
$items = Get-ChildItem -Path $Path | Sort-Object { $_.PSIsContainer }, Name
|
||||
$total = $items.Count
|
||||
|
||||
for ($i = 0; $i -lt $total; $i++) {
|
||||
$item = $items[$i]
|
||||
$isLastItem = ($i -eq ($total - 1))
|
||||
|
||||
$connector = if ($isLastItem) { "└── " } else { "├── " }
|
||||
$itemName = if ($item.PSIsContainer) { "$($item.Name)/" } else { $item.Name }
|
||||
|
||||
"$Prefix$connector$itemName"
|
||||
|
||||
if ($item.PSIsContainer) {
|
||||
$newPrefix = if ($isLastItem) { "$Prefix " } else { "$Prefix│ " }
|
||||
Get-TreeStructure -Path $item.FullName -Prefix $newPrefix -IsLast $isLastItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Get-TreeStructure -Path $vaultParaPath | Out-String | ForEach-Object { $report += $_ }
|
||||
$report += "``````n`n"
|
||||
|
||||
# 顶层内容详情
|
||||
$report += "`n## 📂 顶层目录详情`n`n"
|
||||
$topLevel = Get-ChildItem | Sort-Object { $_.PSIsContainer }, Name
|
||||
|
||||
foreach ($item in $topLevel) {
|
||||
if ($item.PSIsContainer) {
|
||||
$filesInDir = (Get-ChildItem -Path $item.FullName -Recurse -File).Count
|
||||
$mdInDir = (Get-ChildItem -Path $item.FullName -Recurse -Filter "*.md" -File).Count
|
||||
$report += "### 📁 $($item.Name)/`n"
|
||||
$report += "- 总文件: $filesInDir`n"
|
||||
$report += "- Markdown: $mdInDir`n"
|
||||
|
||||
# 列出子目录
|
||||
$subDirs = Get-ChildItem -Path $item.FullName -Directory
|
||||
if ($subDirs.Count -gt 0) {
|
||||
$report += "- 子目录: " + ($subDirs.Name -join ", ") + "`n"
|
||||
}
|
||||
$report += "`n"
|
||||
}
|
||||
}
|
||||
|
||||
# Markdown 文件列表(按目录组织)
|
||||
$report += "`n## 📝 Markdown 文件清单`n`n"
|
||||
|
||||
$mdByDir = $mdFiles | Group-Object { $_.DirectoryName } | Sort-Object Name
|
||||
|
||||
foreach ($group in $mdByDir) {
|
||||
$relPath = $group.Name.Replace($vaultParaPath, ".").Replace("\", "/")
|
||||
$report += "### $relPath`n"
|
||||
foreach ($file in ($group.Group | Sort-Object Name)) {
|
||||
$size = [math]::Round($file.Length / 1KB, 2)
|
||||
$report += "- $($file.Name) ($size KB)`n"
|
||||
}
|
||||
$report += "`n"
|
||||
}
|
||||
|
||||
# 检查是否有 frontmatter
|
||||
$report += "`n## 🏷️ Frontmatter 采样(前10个文件)`n`n"
|
||||
|
||||
$sampleFiles = $mdFiles | Select-Object -First 10
|
||||
|
||||
foreach ($file in $sampleFiles) {
|
||||
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
||||
if ($content -match '^---\s*\n(.*?)\n---') {
|
||||
$frontmatter = $matches[1]
|
||||
$report += "**$($file.Name)**:`n``````yaml`n$frontmatter`n```````n`n"
|
||||
}
|
||||
}
|
||||
|
||||
# 检查内部链接模式
|
||||
$report += "`n## 🔗 链接模式采样`n`n"
|
||||
|
||||
$linkPatterns = @{
|
||||
"WikiLinks" = 0
|
||||
"MarkdownLinks" = 0
|
||||
"Tags" = 0
|
||||
}
|
||||
|
||||
foreach ($file in ($mdFiles | Select-Object -First 50)) {
|
||||
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
||||
if ($content -match '\[\[.*?\]\]') { $linkPatterns["WikiLinks"]++ }
|
||||
if ($content -match '\[.*?\]\(.*?\)') { $linkPatterns["MarkdownLinks"]++ }
|
||||
if ($content -match '#\w+') { $linkPatterns["Tags"]++ }
|
||||
}
|
||||
|
||||
$report += "在前50个文件中发现:`n"
|
||||
$report += "- WikiLinks `[[]]`: $($linkPatterns["WikiLinks"]) 个文件`n"
|
||||
$report += "- Markdown Links `[]()`: $($linkPatterns["MarkdownLinks"]) 个文件`n"
|
||||
$report += "- Tags `#tag`: $($linkPatterns["Tags"]) 个文件`n"
|
||||
|
||||
Pop-Location
|
||||
|
||||
# 保存报告到 my-vault
|
||||
$fullReportPath = Join-Path (Get-Location) $reportPath
|
||||
$report | Out-File -FilePath $fullReportPath -Encoding UTF8
|
||||
|
||||
Write-Host "`n✅ 扫描完成!" -ForegroundColor Green
|
||||
Write-Host "报告已保存到: $fullReportPath" -ForegroundColor Cyan
|
||||
Write-Host "`n下一步: 让 Claude 分析报告并制定迁移计划。" -ForegroundColor Yellow
|
||||
Reference in New Issue
Block a user