Oprava české diakritiky v PowerShellu

Váš skript zapisuje Ä› nebo ? místo ě nebo konzole ukazuje změť znaků? Windows PowerShell 5.1 používá podle příkazu různé kódování. Tady jsou příčiny a správné parametry – a rozbité soubory opravíte v prohlížeči výše.

Funguje s textem a soubory:

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

Například exporty z Excelu, výpisy databází, titulky nebo kód webových stránek.

Opravit

  1. Přetáhněte soubor nebo vložte text
  2. Oprava proběhne automaticky
  3. Zkopírujte nebo stáhněte
nebo soubor jednoduše přetáhněte sem

Jádro problému: každý příkaz má jiné kódování

Ve Windows PowerShellu 5.1 má skoro každý příkaz vlastní výchozí kódování: Get-Content čte soubory bez BOM jako ANSI (v české verzi Windows je to Windows-1250), Out-File a > zapisují UTF-16, Set-Content zapisuje ANSI a Export-Csv ASCII. PowerShell 7 to sjednotil a všude používá UTF-8 bez BOM.

Soubor v UTF-8 přečtený příkazem Get-Content v PowerShellu 5.1

Před

Uživatel;Oddělení;Pobočka
Jiří Dvořák;Prodej;Třebíč
Zdeněk Černý;Nákup;Brno

Po

Uživatel;Oddělení;Pobočka
Jiří Dvořák;Prodej;Třebíč
Zdeněk Černý;Nákup;Brno

Správné čtení a zápis souborů

  • Get-Content data.csv -Encoding UTF8 čte soubory UTF-8 správně i bez BOM.
  • Set-Content, Out-File a Add-Content zapisují UTF-8 s -Encoding UTF8 – ve verzi 5.1 vždy s BOM.
  • Export-Csv data.csv -Encoding UTF8 -NoTypeInformation místo výchozího ASCII, které nahrazuje české písmena znakem ?.
  • Pro všechny příkazy najednou: $PSDefaultParameterValues['*:Encoding'] = 'utf8' na začátku skriptu.

Invoke-RestMethod a Invoke-WebRequest

Pokud server neuvede znakovou sadu v hlavičce Content-Type, dekóduje Windows PowerShell 5.1 odpověď jako ISO-8859-1. Odpovědi v UTF-8 pak obsahují Ä› a Å™. Řešení: stáhnout odpověď jako bajty a dekódovat ji sami, například [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).

Soubory skriptů s diakritikou

Uložíte-li skript jako UTF-8 bez BOM, přečte ho Windows PowerShell 5.1 jako ANSI. Písmena v řetězcích jako Write-Host "Příliš žluťoučký kůň" pak vypadají jako Příliš ĹľluĹĄouÄŤkĂ˝ kĹŻĹ. Ukládejte soubory .ps1 jako UTF-8 s BOM – ve VS Code přes kódování ve stavovém řádku, v Notepad++ přes Encoding → UTF-8-BOM.

Konzole

Pokud špatné znaky ukazuje jen okno konzole, např. čáry a rámečky místo písmen, bývá soubor v pořádku – konzole čte UTF-8 jako DOS kódovou stránku 852. Výstup přepnete příkazem [Console]::OutputEncoding = [Text.Encoding]::UTF8. U dat předávaných externím programům nastavte také $OutputEncoding = [Text.Encoding]::UTF8.

Pokud už byl soubor zapsán rozbitě, přetáhněte ho do pole výše: Mojibuster opraví Ä› a podobné znaky a převede soubory ANSI (Windows-1250) na UTF-8. Pokud soubor už obsahuje otazníky, je text ztracen – viz co je mojibake.

Časté otázky

Jakou verzi PowerShellu mám?

Ukáže to $PSVersionTable.PSVersion. 5.1 je Windows PowerShell vestavěný ve Windows, od verze 7 se jmenuje jen PowerShell a ve výchozím stavu používá UTF-8.

Proč Excel otevírá můj CSV z PowerShellu špatně?

PowerShell 7 zapisuje UTF-8 bez BOM, který Excel nepozná. Použijte -Encoding utf8BOM nebo soubor uložte s BOM v Mojibusteru. Víc o Excelu a rozsypaném čaji v CSV.

Potřebuji chcp 65001?

Jen u programů, které se řídí kódovou stránkou konzole. Uvnitř PowerShellu stačí [Console]::OutputEncoding.

Další návody