2016年6月3日星期五

使用PowerShell多層資料夾大量轉換檔案繁簡中文

前幾天公司叫我把一個ASP.NET MVC專案由繁體中文轉換成簡體中文,
雖然都知道只是轉字不轉語法,但要求是這樣都沒辦法。
第一時間就想到用古法知名的ConvertZ,但原來ConvertZ只是支援一層資料夾,並不支援Recursive轉換檔案。

還是自己乖乖做小程式,網上一些文章介紹兩種方法,
一是引用VisualBasic.Runtime的Strings.StrConv功能,
二是引用Microsoft Office的Microsoft.Office.Interop.Word中的簡繁互換,
但公司是英文版Office,沒提供Language Pack,所以沒有安裝那個中文繁簡轉換增益集。
最後只可以選擇前者,但完成後,發現轉換不到簡體,既沒有亂碼,
檔案都是有修改過,但文字原封不動。
不知道是否英文Windows + 英文.NET Framework影響,都沒有研究下去。

突然想起之前SSIS專案用過Uniconv,(見UniConv - 超強轉碼工具 BIG5/GB/UTF8/Unicode)
Uniconv除了轉換內碼如Big5,UTF8等等,還可以繁簡轉換的。
花了一點時間研究如何用CMD做Loop之後.......
還是使用PowerShell更簡單。

完成後的程式碼如下:

#取得所有主資料夾和子資料夾所有檔案,可自行設定Filter
$files_table = Get-ChildItem -Path "C:\Source\MVCSite" -Include *.cshtml,*.cs -Recurse
#建立暫存資料夾供uniconv使用
$temp_folder = "C:\Source\Translated\"
foreach ($file in $files_table)
{
    #取得個別檔案所在的路徑
    $origin_folder = Split-Path -Path $file.fullname
    #複製至暫存資料夾的路徑
    $temp_file = $temp_folder + $file.Name
    #uniconv命令行
    $arg = 'UTF8 "' + $file.FullName + '" UTF8 "' + $temp_file + '" ToSimplifiedChinese'
    #write-host是debug用,類似echo或debug.print
    #write-host $arg 
    #啟動uniconv, wait參數是等待一個程序完成才執行下一個
    Start-Process -FilePath "C:\uniconv\uniconv.exe" -Wait -ArgumentList $arg
    #複製回原本的資料夾
    Copy-Item -Path $temp_file -Destination $origin_folder -Force
    #刪除暫存檔案
    Remove-Item $temp_file
}
程序上沒太多技術細節,但我轉換了多層資料夾,大量檔案都沒有問題,而且速度都很快。

要在PowerShell執行多行程序可以使用";"分號代替LineBreak。
$files_table = Get-ChildItem -Path "C:\Source\MVCSite" -Include *.cshtml,*.cs -Recurse;$temp_folder = "C:\Source\Translated\";foreach ($file in $files_table){ $origin_folder = Split-Path -Path $file.fullname;$temp_file = $temp_folder + $file.Name;$arg = 'UTF8 "' + $file.FullName + '" UTF8 "' + $temp_file + '" ToSimplifiedChinese';Start-Process -FilePath "C:\uniconv\uniconv.exe" -Wait -ArgumentList $arg;Copy-Item -Path $temp_file -Destination $origin_folder -Force;Remove-Item $temp_file;}

參考:
[C#].net的簡繁轉換
CODE-封裝Office繁簡轉換服務
用vb.net自製一個簡繁互換!!不用再開Word去互換