Oprava slovenskej diakritiky v PowerShelli

Váš skript zapisuje ľ alebo ? namiesto ľ alebo konzola ukazuje zmes znakov? Windows PowerShell 5.1 používa podľa príkazu rôzne kódovanie. Tu sú príčiny a správne parametre – a pokazené súbory opravíte v prehliadači vyššie.

Funguje s textom aj súbormi:

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

Napríklad exporty z Excelu, výpisy databáz, titulky alebo kód webových stránok.

Opraviť

  1. Pretiahnite súbor alebo vložte text
  2. Oprava prebehne automaticky
  3. Skopírujte alebo stiahnite
alebo súbor jednoducho pretiahnite sem

Jadro problému: každý príkaz má iné kódovanie

Vo Windows PowerShelli 5.1 má takmer každý príkaz vlastné predvolené kódovanie: Get-Content číta súbory bez BOM ako ANSI (v slovenskej verzii Windows je to Windows-1250), Out-File a > zapisujú UTF-16, Set-Content zapisuje ANSI a Export-Csv ASCII. PowerShell 7 to zjednotil a všade používa UTF-8 bez BOM.

Súbor v UTF-8 prečítaný príkazom Get-Content v PowerShelli 5.1

Pred

Používateľ;Oddelenie;Pobočka
Ján Kováč;Predaj;Žilina
Ľudmila Horváthová;Nákup;Košice

Po

Používateľ;Oddelenie;Pobočka
Ján Kováč;Predaj;Žilina
Ľudmila Horváthová;Nákup;Košice

Správne čítanie a zápis súborov

  • Get-Content data.csv -Encoding UTF8 číta súbory UTF-8 správne aj bez BOM.
  • Set-Content, Out-File a Add-Content zapisujú UTF-8 s -Encoding UTF8 – vo verzii 5.1 vždy s BOM.
  • Export-Csv data.csv -Encoding UTF8 -NoTypeInformation namiesto predvoleného ASCII, ktoré nahrádza slovenské písmená znakom ?.
  • Pre všetky príkazy naraz: $PSDefaultParameterValues['*:Encoding'] = 'utf8' na začiatku skriptu.

Invoke-RestMethod a Invoke-WebRequest

Ak server neuvedie znakovú sadu v hlavičke Content-Type, dekóduje Windows PowerShell 5.1 odpoveď ako ISO-8859-1. Odpovede v UTF-8 potom obsahujú ľ a Å¡. Riešenie: stiahnuť odpoveď ako bajty a dekódovať ju sami, napríklad [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).

Súbory skriptov s diakritikou

Ak uložíte skript ako UTF-8 bez BOM, prečíta ho Windows PowerShell 5.1 ako ANSI. Písmená v reťazcoch ako Write-Host "Kŕdeľ ďatľov" potom vyzerajú ako KĹ•deÄľ ÄŹatÄľov. Ukladajte súbory .ps1 ako UTF-8 s BOM – vo VS Code cez kódovanie v stavovom riadku, v Notepad++ cez Encoding → UTF-8-BOM.

Konzola

Ak zlé znaky ukazuje iba okno konzoly, napr. čiary a rámčeky namiesto písmen, býva súbor v poriadku – konzola číta UTF-8 ako DOS kódovú stránku 852. Výstup prepnete príkazom [Console]::OutputEncoding = [Text.Encoding]::UTF8. Pri dátach odovzdávaných externým programom nastavte aj $OutputEncoding = [Text.Encoding]::UTF8.

Ak už bol súbor zapísaný pokazene, presuňte ho do poľa vyššie: Mojibuster opraví ľ a podobné znaky a prevedie súbory ANSI (Windows-1250) na UTF-8. Ak súbor už obsahuje otázniky, je text stratený – pozri čo je mojibake.

Časté otázky

Akú verziu PowerShellu mám?

Ukáže to $PSVersionTable.PSVersion. 5.1 je Windows PowerShell zabudovaný vo Windows, od verzie 7 sa volá iba PowerShell a predvolene používa UTF-8.

Prečo Excel otvára môj CSV z PowerShellu zle?

PowerShell 7 zapisuje UTF-8 bez BOM, ktorý Excel nepozná. Použite -Encoding utf8BOM alebo súbor uložte s BOM v Mojibusteri. Viac o Exceli a rozsypanom čaji v CSV.

Potrebujem chcp 65001?

Len pri programoch, ktoré sa riadia kódovou stránkou konzoly. V samotnom PowerShelli stačí [Console]::OutputEncoding.

Ďalšie návody