Powershellでの、文字コード変換

シェアする

よくあるテキストファイルの文字コード変換ですが、サイズが大きくなるとエディターで開いて、文字コードを指定して保存して・・・というのが辛くなりますよね。 そこで、Windows標準機能のPowershellで、文字コードを変換してみます。

前提

以下の例では、Windows上でUnicode(UTF-16リトルエイディアン)で保存されているファイルを、シフトJISに変換するサンプルになっています。要件に合わせて、適宜指定する文字コードを変えてください 変数[$From]に変換前の、変数[$To]に変換後の、ファイルフルパスを予め入れているものとします

例)
$FromFilePath = "C:\Temp\unicode.txt"
$ToFilePath = `C:\Temp\sjis.txt`

ワンライナー版

数十MB程度までのファイルを文字コード変換するなら、標準のコマンドレットで簡単にできます。 (ただし、powershellプロセスが、ファイルサイズ+αのメモリーを消費します)

Get-Content -Encoding Unicode $FromFilePath | Set-Content $ToFilePath

dotNet Framework 版(StreamReader、StreamWriter)

数百MBあるような大き目のファイルを文字コード変換するときは、標準のコマンドレット(get-content、set-content)でやると、システムリソースを消費しすぎるため、StreamReader、StreamWriterクラスを使って、ファイルI/Oをバッファリングしてあげます。速度もそこそこで、メモリー使用量も抑えられのがありがたい。

Function Convert-Charset
{
    param
    (
    [String] $From,
    [String] $To
    )

    # set buffer size to 4MB
    $StreamReaderBufferSize = 4 * 1024 * 1024
    $StreamWriterBufferSize = 4 * 1024 * 1024

    Try
    {
        # charset name: utf-8 Shift_Jis Unicode
        # reference http://www.atmarkit.co.jp/ait/articles/0304/11/news004.html

        $Reader = New-Object System.IO.StreamReader( $From, `
            [Text.Encoding]::GetEncoding(`Unicode`), $false, `
            $StreamReaderBufferSize)
        $Writer = New-Object System.IO.StreamWriter( $To, `
            $false, [Text.Encoding]::GetEncoding(`Shift_Jis`), `
            $StreamWriterBufferSize)

            
        # read all line, and write all line
        While( -not ($Reader.EndOfStream) )
        {
            $Writer.WriteLine( $Reader.ReadLine() )
        }

    } Catch {
        Write-Error $Error[0].Exception.ErrorRecord
        throw $_.Exception
        
    } Finally {
        $Writer.Close()
        $Reader.Close()
    }

}

convert-charset -From $FromFilePath -To $ToFilePath

バッファーサイズは、実行環境のメモリーに余裕があれば、例では4MBですが、32MB程度に増やした方がスループットが出る場合もあるので、試しながら調整してください。 文字コード指定のキーワードは、@ITさんの記事が分かりやすいので、参考にされてください