Коренът на проблема: всяка команда има своя кодировка
В Windows PowerShell 5.1 почти всяка команда има собствена кодировка по подразбиране. Get-Content чете файл без BOM като ANSI (в българската Windows това е Windows-1251), Out-File и > пишат UTF-16, Set-Content пише ANSI, а Export-Csv — ASCII, при което кирилицата се превръща в ?. PowerShell 7 ги обединява: навсякъде UTF-8 без BOM.
Преди
Служител;Отдел;Град Здравко Йорданов;Продажби;Шумен Юлия Щерева;Доставки;Търговище
След
Служител;Отдел;Град Здравко Йорданов;Продажби;Шумен Юлия Щерева;Доставки;Търговище
Четене и писане на файлове
Get-Content data.csv -Encoding UTF8чете UTF-8 правилно дори без BOM.- Ако файлът е в Windows-1251 и искате да го прочетете изрично, в PowerShell 7 задайте
-Encoding windows-1251. В Windows PowerShell 5.1 за това служи-Encoding Default: ползва се ANSI кодировката на системата. Set-Content,Out-FileиAdd-Contentпишат UTF-8 с-Encoding UTF8. Във версия 5.1 това е винаги UTF-8 с BOM.Export-Csv data.csv -Encoding UTF8 -NoTypeInformation -Delimiter ";"вместо ASCII по подразбиране, който заменя кирилицата с?. Точката и запетаята е нужна, за да раздели Excel колоните в българска Windows.- За всички команди наведнъж:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'в началото на скрипта.
Уеб заявки с Invoke-RestMethod и Invoke-WebRequest
Ако сървърът не е посочил набор от знаци в Content-Type, Windows PowerShell 5.1 декодира отговора като ISO-8859-1. Тогава UTF-8 отговорите съдържат Здравей. Вземете отговора като байтове и го декодирайте сами, например с [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).
Скриптове с кирилица
Ако запишете скрипт в UTF-8 без BOM, Windows PowerShell 5.1 го чете като ANSI. Тогава Write-Host "Здравей" извежда Здравей. Записвайте .ps1 файловете в UTF-8 с BOM: във VS Code чрез кодировката в лентата за състоянието, в Notepad++ чрез менюто за кодировки (Encoding) → UTF-8-BOM.
Конзолата
Ако само прозорецът на конзолата показва грешни знаци като ╨Ч╨┤╤А╨░╨▓╨╡╨╣, файлът често е наред: конзолата чете UTF-8 като DOS кодова таблица. Превключете изхода с [Console]::OutputEncoding = [Text.Encoding]::UTF8. За данни, които подавате на външни програми, задайте и $OutputEncoding = [Text.Encoding]::UTF8.
Ако файлът вече е записан повреден, пуснете го в полето по-горе: Mojibuster поправя Здравей и подобни и превръща ANSI файловете (Windows-1251) в UTF-8. Ако във файла вече има въпросителни, текстът е загубен. Повече: какво е mojibake.
Често задавани въпроси
Коя версия на PowerShell имам?
$PSVersionTable.PSVersion я показва. 5.1 е вграденият в Windows Windows PowerShell; от 7 нататък се казва просто PowerShell и по подразбиране ползва UTF-8.
Защо Excel отваря грешно CSV от PowerShell?
PowerShell 7 пише UTF-8 без BOM, който Excel не разпознава. Използвайте -Encoding utf8BOM или запишете файла с BOM в Mojibuster. Повече: странни символи в Excel.
Трябва ли ми chcp 65001?
Само за програми, които следват кодовата таблица на конзолата. В самия PowerShell стига [Console]::OutputEncoding.