コンソールの文字化けを防ぐ
- PowerhsellファイルをUTF-8 BOMありで保存する(Shift JISで保存した場合、Shift JIS定義内でも日本語含むパスが文字化けする)
- Powershellのコンソールで日本語を含む文字コードになっていることを確認する(MSゴシックなど)
- Powerhsellファイルに「chcp 65001」を記載する(不要?)
ファイルの文字化けを防ぐ
- Powershell 5.1(2024/03時点デフォルト?)でSet-Contentを使用するとShift JISやUTF-8 BOMなしでのファイル出力がうまくいかない(ただし、PowerShell 7.0以降でutf8NoBOM追加)
- Get-ContentでUTF-8は読み込めたが、Shift JISの読み込みはうまくいかない
- そのためSystem.IO.Fileを使用する。以下正規表現で置換するサンプル
UTF-8 BOMありで保存すること!
$path = 'C:\Users\user\Documents\test.txt'
$sjis = [System.Text.Encoding]::GetEncoding(932)
$utf8_bomless = New-Object System.Text.UTF8Encoding $False
$lines = [System.IO.File]::ReadAllLines($path, $sjis)
$result = @()
foreach ($line in $lines) {
$result += $line -replace '^bar1$', 'bar①' # 正規表現で置換する場合
if ($line -match '^bar2$') {
# 正規表現に一致した行の下に追加する場合
$result += $line
$result += 'bar2.1'
$result += 'bar2.2'
}
}
### ここから、改行コードと最終行が空行かどうかの判定のためだけの処理
$text = [System.IO.File]::ReadAllText($path, $sjis)
$split = $text.Split("`r")
$s = ''
if ($split.Length -gt 1) {
if ($split[1].StartsWith("`n")) {
$s = "`r`n"
} else {
$s = "`r"
}
} else {
$s = "`n"
}
$output = $result -join $s
if ($text -match ($s + "$")) { # 最終行が空行の場合追加する
$output = $output + $s
}
### ここまで
[System.IO.File]::WriteAllText($path, $output, $utf8_bomless)
# WriteAllLinesは最後に空行が追加されること、改行コードがCRLFに変わることから使用できない
ReadAllTextのみで実現する場合より複雑になる
$path = 'C:\Users\user\Documents\test.txt'
$sjis = [System.Text.Encoding]::GetEncoding(932)
$utf8_bomless = New-Object System.Text.UTF8Encoding $False
$text = [System.IO.File]::ReadAllText($path, $sjis)
$split = $text.Split("`r")
$s = ''
if ($split.Length -gt 1) {
if ($split[1].StartsWith("`n")) {
$s = "`r`n"
} else {
$s = "`r"
}
} else {
$s = "`n"
}
$array = @(
('bar1', 'bar①'),
('bar2', @'
bar2
bar2.1
bar2.2
'@
), ('foo1', 'foo①'))
foreach ($item in $array) {
# この順番だと恐らくうまくいく
$text = $text -replace ($s + $item[0] + $s), ($s + ($item[1] -join $s) + $s)
$text = $text -replace ('^' + $item[0] + $s), (($item[1] -join $s) + $s)
$text = $text -replace ($s + $item[0] + '$'), ($s + ($item[1] -join $s))
$text = $text -replace ('^' + $item[0] + '$'), ($item[1] -join $s)
}
[System.IO.File]::WriteAllText($path, $text, $utf8_bomless)