はじめに
本記事は以下のイベントに参加しております。
筆者の環境は以下のとおりです。
・Windows10 Home(22H2)
・PSVersion 5.1.19041.3031(バージョンは各自$PSVersionTableで確認してください)
また、OS実行ポリシーの確認及び変更が必要な場合があります。
背景
・(表面上は見えないけれど)ANSI前提で取込処理されている箇所に
UTF8のファイルを入れたら文字化けしたので対応できないでしょうか。
といった問い合わせが来ました。
・現状のシステム構築している環境単体ではできないが
(汎用的なDBの文字コードを後から変更もしたくないですし...)
取込前に変換することで対応できるかもしれない。
前提
・BOM付UTF8しか判定できない。
・nkf等を利用したくない
(色々なリスクを考慮して素のPowershellで処理したい)。
(+αメンテナンスの期間を見ても放置気味なので利用したくない)
記述したスクリプト
・コメントや内容から判断してもらえれば助かります
■パターン1(フォルダを指定して配下のCSVを全変換する)
<#
・特定のフォルダ内のCSVを全てUTF-8からShift-JISに変換するスクリプト
#>
# 引数でフォルダのパスを受け取る
Param ($arg0)
# フォルダからファイルの一覧(CSVのみ)を取得する
$folderFileList = Get-ChildItem -File $arg0\*.csv
# 取得したファイル数分ループする
foreach ($item in $folderFileList)
{
# ここから文字コードがUTF-8かの判定処理
Byte[] $data = Get-Content $item -Encoding Byte
# bom付きかどうかを判定する
$tmp = ""
if ($data.Length -ge 3) {
# 取得したByte文字列の長さが3以上だったら
foreach($element in $data[0..2])
{
# 1バイトを2桁の16進数に変換する
$tmp = $tmp + $element.ToString("X2")
# 先頭3バイトが"EFBBBF"かどうかで、utf8かどうかを判断する
}
}
if ($tmp -eq "EFBBBF") {
# Out-FileでEncoding defaultを指定しShift-JISに変換
# 同じファイル名で直接上書きできない為、「元ファイル => 変換後ファイル => 元ファイル」と書込んでから変換後ファイルを削除する
Get-Content -Encoding UTF8 $item | Out-File -Encoding default $arg0\SJIS_From_UTF8.csv
Get-Content -Encoding default $arg0\SJIS_From_UTF8.csv | Out-File -Encoding default $item
Remove-item $arg0\SJIS_From_UTF8.csv
}
}
■パターン2(フォルダとファイルを指定して変換する)
<#
・CSVをUTF-8からShift-JISに変換するスクリプト
#>
# 引数でフォルダパスとファイルパスを受け取る
Param(
$folder_path,
$file_path
)
# ここから文字コードがUTF-8かの判定処理
Byte[] $data = Get-Content $file_path -Encoding Byte
# bom付きかどうかを判定する
$tmp = ""
if ($data.Length -ge 3) {
# 取得したByte文字列の長さが3以上だったら
foreach($element in $data[0..2])
{
# 1バイトを2桁の16進数に変換する
$tmp = $tmp + $element.ToString("X2")
# 先頭3バイトが"EFBBBF"かどうかで、UTF-8かどうかを判断する
}
}
if ($tmp -eq "EFBBBF") {
# Out-FileでEncoding defaultを指定しShift-JISに変換
# 同じファイル名で直接上書きできない為、「元ファイル => 変換後ファイル => 元ファイル」と書込んでから変換後ファイルを削除する
Get-Content -Encoding UTF8 $file_path | Out-File -Encoding default $folder_path\SJIS_From_UTF8.csv
Get-Content -Encoding default $folder_path\SJIS_From_UTF8.csv | Out-File -Encoding default $file_path
Remove-item $folder_path\SJIS_From_UTF8.csv
}
文字コード判定参考