递归修复目录中纯文本文件的损坏换行符(支持Linux、Mac、Windows平台)
递归修复目录中纯文本文件的损坏换行符(支持Linux、Mac、Windows平台)
嘿,这个需求简直是日常处理文件时的噩梦!既要区分文本和二进制(还不能靠扩展名),又要精准修复各种奇葩的换行符损坏,还得跨平台操作。别慌,我给你整理了一套实用的方案,分平台给你说:
核心需求回顾
先再明确下咱们要做的事:
- 跳过二进制文件和正常Unix换行(LF)的文本文件
- 把
CRCR+LF(多个CR加LF)修复成标准CRLF - 删掉单独存在的CR(经典Mac换行)
- 优先保留原有正常换行,万不得已才统一转LF
Linux/Mac 平台方案
咱们用find+file+perl组合来搞定,这一套在类Unix系统上非常靠谱:
执行命令
find /path/to/your/target/dir -type f -exec sh -c ' for file do # 判断是否为文本文件(file命令会自动识别编码类型,包括UTF-16、Latin-1) if file -b "$file" | grep -q "text"; then # 先备份原文件,后缀加.bak,防止操作失误 cp "$file" "$file.bak" # 用perl处理换行符: # 1. 把一个或多个CR+LF替换成单个CRLF # 2. 删掉不跟LF的单独CR perl -pi -e 's/\r+\n/\r\n/g; s/\r(?!\n)//g' "$file" fi done ' sh {} +
细节说明
file -b "$file":输出文件的类型描述,过滤出包含"text"的文件(不管是UTF-8、UTF-16还是Latin-1,都会被识别为文本)- 备份步骤非常重要!处理完确认没问题后,再用
find /path/to/dir -name "*.bak" -delete删除备份 - 如果最后你接受统一转成Unix换行(LF),可以把perl的命令改成:
perl -pi -e 's/\r+\n/\n/g; s/\r//g' "$file"
Windows 平台方案
用PowerShell来实现,不需要额外安装工具,系统自带就能搞定:
执行脚本
# 替换成你的目标目录路径 $targetDirectory = "C:\your\target\directory" # 递归遍历所有文件 Get-ChildItem -Path $targetDirectory -Recurse -File | ForEach-Object { $currentFile = $_ try { # 尝试读取文件内容为文本,读取失败的就是二进制文件 $fileContent = Get-Content -Path $currentFile.FullName -Raw -ErrorAction Stop # 备份原文件 Copy-Item -Path $currentFile.FullName -Destination "$($currentFile.FullName).bak" -Force # 修复换行符: # 1. 把多个CR+LF替换成标准CRLF # 2. 删除不跟LF的单独CR $fixedContent = $fileContent -replace '\r+\n', "`r`n" -replace '\r(?!\n)', '' # 写回文件,-NoNewline避免额外添加多余换行 Set-Content -Path $currentFile.FullName -Value $fixedContent -Force -NoNewline } catch { # 二进制文件读取失败,直接跳过 Write-Host "跳过二进制文件:$($currentFile.FullName)" } }
细节说明
- 直接用
Get-Content -Raw尝试读取文件,二进制文件会抛出错误,自动跳过,完美区分文本和二进制 - 同样保留了备份步骤,确认无误后可以手动删除
.bak文件 - 如果要统一转成Unix换行(LF),把替换规则改成:
$fixedContent = $fileContent -replace '\r+\n', "n" -replace '\r', ''`
通用注意事项
- 先测试再批量:找几个有问题的测试文件先跑一遍,确认修复效果符合预期后再批量处理整个目录
- 编码问题:用户提到不需要保留编码,只保留内容,这套方案处理后编码可能会有变化,但核心内容会完整保留
- 大文件处理:对于超大文本文件,perl和PowerShell的处理效率都不错,不用担心卡顿
备注:内容来源于stack exchange,提问作者icodestuff




