Как да поправите кодировката в PowerShell

Скриптът записва Здравей или ??????? вместо „Здравей“, а конзолата показва странни знаци? Windows PowerShell 5.1 избира кодировка по различен начин за всяка команда. Ето причините и правилните параметри, а повредени файлове можете да поправите в браузъра по-горе.

Работи с текст и с тези файлове:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • SMI
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

Например експорти от Excel и счетоводни програми, архиви на бази данни, субтитри или код на сайтове.

Поправяне

  1. Пуснете файл или поставете текст
  2. Поправката е автоматична
  3. Копирайте или изтеглете
или просто пуснете файл тук

Коренът на проблема: всяка команда има своя кодировка

В 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.

UTF-8 файл, прочетен с Get-Content в PowerShell 5.1

Преди

Служител;Отдел;Град
Здравко Йорданов;Продажби;Шумен
Юлия Щерева;Доставки;Търговище

След

Служител;Отдел;Град
Здравко Йорданов;Продажби;Шумен
Юлия Щерева;Доставки;Търговище

Четене и писане на файлове

  • 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.

Други ръководства