本文目录导读:

Python脚本(最通用,推荐)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量去除文件中的特殊字符
支持单个文件或整个目录
"""
import os
import re
import sys
import argparse
def remove_special_chars(text, keep_chinese=False, keep_punctuation=False):
"""
去除特殊字符
:param text: 输入文本
:param keep_chinese: 是否保留中文字符
:param keep_punctuation: 是否保留标点符号
"""
if keep_chinese:
# 保留中文、字母、数字、空格、标点
if keep_punctuation:
pattern = r'[^\u4e00-\u9fff\w\s,。!?、;:""''()【】《》\-\.\,\!\?\;\:\(\)\[\]\{\}]'
else:
pattern = r'[^\u4e00-\u9fff\w\s]'
else:
# 只保留字母、数字、空格
if keep_punctuation:
pattern = r'[^\w\s,。!?、;:""''()【】《》\-\.\,\!\?\;\:\(\)\[\]\{\}]'
else:
pattern = r'[^\w\s]'
return re.sub(pattern, '', text)
def process_file(filepath, backup=True, **kwargs):
"""处理单个文件"""
# 只处理文本文件
if not filepath.endswith(('.txt', '.csv', '.md', '.json', '.xml', '.html', '.py', '.js', '.css')):
print(f"跳过非文本文件: {filepath}")
return
try:
# 读取文件
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
# 备份原始文件
if backup:
backup_path = filepath + '.bak'
with open(backup_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"已备份: {backup_path}")
# 处理内容
new_content = remove_special_chars(content, **kwargs)
# 写回文件
with open(filepath, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f"已处理: {filepath}")
except Exception as e:
print(f"处理失败 {filepath}: {str(e)}")
def process_directory(directory, recursive=False, **kwargs):
"""处理整个目录"""
for root, dirs, files in os.walk(directory):
for file in files:
filepath = os.path.join(root, file)
process_file(filepath, **kwargs)
if not recursive:
break # 只处理当前目录
def main():
parser = argparse.ArgumentParser(description='批量去除文件中的特殊字符')
parser.add_argument('path', help='文件或目录路径')
parser.add_argument('-r', '--recursive', action='store_true', help='递归处理子目录')
parser.add_argument('-c', '--chinese', action='store_true', help='保留中文字符')
parser.add_argument('-p', '--punctuation', action='store_true', help='保留中文标点符号')
parser.add_argument('-n', '--no-backup', action='store_true', help='不创建备份')
args = parser.parse_args()
kwargs = {
'keep_chinese': args.chinese,
'keep_punctuation': args.punctuation,
'backup': not args.no_backup
}
if os.path.isfile(args.path):
process_file(args.path, **kwargs)
elif os.path.isdir(args.path):
process_directory(args.path, args.recursive, **kwargs)
else:
print(f"路径不存在: {args.path}")
sys.exit(1)
if __name__ == '__main__':
main()
使用方法:
# 处理单个文件 python remove_special_chars.py file.txt # 处理整个目录(递归) python remove_special_chars.py ./documents -r # 保留中文字符 python remove_special_chars.py file.txt -c # 保留中文标点 python remove_special_chars.py file.txt -c -p # 不创建备份 python remove_special_chars.py file.txt -n
Shell脚本(Linux/Mac)
#!/bin/bash
# 批量去除特殊字符脚本
# 用法: ./remove_special.sh <文件或目录>
remove_chars() {
local file="$1"
# 只处理文本文件
if ! file "$file" | grep -q "text"; then
echo "跳过非文本文件: $file"
return
fi
# 备份
cp "$file" "${file}.bak"
echo "已备份: ${file}.bak"
# 去除特殊字符(保留字母、数字、空格、换行)
sed -i 's/[^a-zA-Z0-9 \n\r\t]//g' "$file"
# 如果是中文环境,也可以保留中文
# sed -i 's/[^a-zA-Z0-9\u4e00-\u9fff \n\r\t]//g' "$file"
# 压缩多余空格
sed -i 's/ */ /g; s/^ *//; s/ *$//' "$file"
echo "已处理: $file"
}
# 处理目录
process_dir() {
local dir="$1"
local recursive="$2"
if [ "$recursive" = "true" ]; then
find "$dir" -type f | while read file; do
remove_chars "$file"
done
else
for file in "$dir"/*; do
if [ -f "$file" ]; then
remove_chars "$file"
fi
done
fi
}
# 主逻辑
if [ -z "$1" ]; then
echo "用法: $0 <文件或目录>"
exit 1
fi
if [ -f "$1" ]; then
remove_chars "$1"
elif [ -d "$1" ]; then
echo "是否递归处理子目录? (y/n)"
read recursive
if [ "$recursive" = "y" ] || [ "$recursive" = "Y" ]; then
process_dir "$1" "true"
else
process_dir "$1" "false"
fi
else
echo "路径不存在: $1"
exit 1
fi
PowerShell脚本(Windows)
# remove_special_chars.ps1
# 批量去除文件中的特殊字符
param(
[Parameter(Mandatory=$true)]
[string]$Path,
[switch]$Recursive,
[switch]$KeepChinese,
[switch]$NoBackup
)
function Remove-SpecialChars {
param(
[string]$Text,
[bool]$KeepChinese
)
if ($KeepChinese) {
# 保留中文字符、字母、数字、空格、标点
$pattern = '[^\u4e00-\u9fff\w\s,。!?、;:""''()【】《》\-\.\,\!\?\;\:\(\)\[\]\{\}]'
} else {
# 只保留字母、数字、空格
$pattern = '[^\w\s]'
}
return $Text -replace $pattern, ''
}
function Process-File {
param(
[string]$FilePath,
[bool]$Backup,
[bool]$KeepChinese
)
# 检查文件类型
$textExtensions = @('.txt', '.csv', '.md', '.json', '.xml', '.html', '.py', '.js', '.css')
$ext = [System.IO.Path]::GetExtension($FilePath)
if ($textExtensions -notcontains $ext) {
Write-Host "跳过非文本文件: $FilePath" -ForegroundColor Yellow
return
}
try {
# 读取文件
$content = Get-Content $FilePath -Raw -Encoding UTF8
# 备份
if ($Backup) {
$backupPath = "$FilePath.bak"
Set-Content $backupPath $content -Encoding UTF8
Write-Host "已备份: $backupPath" -ForegroundColor Green
}
# 处理内容
$newContent = Remove-SpecialChars -Text $content -KeepChinese $KeepChinese
# 写回文件
Set-Content $FilePath $newContent -Encoding UTF8
Write-Host "已处理: $FilePath" -ForegroundColor Green
} catch {
Write-Host "处理失败 $FilePath`: $_" -ForegroundColor Red
}
}
# 主逻辑
if (Test-Path $Path -PathType Container) {
# 处理目录
$files = if ($Recursive) {
Get-ChildItem $Path -Recurse -File
} else {
Get-ChildItem $Path -File
}
foreach ($file in $files) {
Process-File -FilePath $file.FullName -Backup (!$NoBackup) -KeepChinese $KeepChinese
}
} elseif (Test-Path $Path -PathType Leaf) {
Process-File -FilePath $Path -Backup (!$NoBackup) -KeepChinese $KeepChinese
} else {
Write-Host "路径不存在: $Path" -ForegroundColor Red
exit 1
}
使用方式:
# 处理单个文件 .\remove_special_chars.ps1 -Path "C:\file.txt" # 递归处理目录 .\remove_special_chars.ps1 -Path "C:\documents" -Recursive # 保留中文字符 .\remove_special_chars.ps1 -Path "file.txt" -KeepChinese # 不创建备份 .\remove_special_chars.ps1 -Path "file.txt" -NoBackup
自定义特殊字符列表版本
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
自定义特殊字符去除脚本
"""
import os
import re
# 自定义要保留的字符
KEEP_CHARS = set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,!?;:'\"()-_")
def custom_remove(text):
"""只保留KEEP_CHARS中的字符"""
return ''.join(c for c in text if c in KEEP_CHARS or c in '\n\r\t')
def process_file(filepath):
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
new_content = custom_remove(content)
# 备份
with open(filepath + '.bak', 'w', encoding='utf-8') as f:
f.write(content)
with open(filepath, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f"处理完成: {filepath}")
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
print("用法: python custom_remove.py <文件或目录>")
sys.exit(1)
path = sys.argv[1]
if os.path.isfile(path):
process_file(path)
elif os.path.isdir(path):
for root, dirs, files in os.walk(path):
for file in files:
process_file(os.path.join(root, file))
使用建议
- 备份很重要:所有脚本都包含备份功能,建议先测试
- 测试运行:先用单个文件测试效果
- 编码问题:脚本默认使用UTF-8编码,其他编码可能需调整
- 性能考虑:处理大文件时,Python版本性能更好
- 安全性:不要处理二进制文件,可能导致文件损坏
选择最适合您需求的版本,根据需要调整保留字符的规则。