Popravek kodiranja znakov v PowerShellu

Vaša skripta piše ÄŤ ali ? namesto č ali pa konzola kaže nečitljivo besedilo? Windows PowerShell 5.1 uporablja različno kodiranje glede na ukaz. Tu so vzroki in pravi parametri – že pokvarjene datoteke pa lahko popravite v brskalniku zgoraj.

Deluje z besedilom in datotekami:

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

Na primer izvozi iz Excela, izpisi baz podatkov, podnapisi za filme ali koda spletnih strani.

Popravi

  1. Povlecite datoteko ali prilepite besedilo
  2. Popravilo poteka samodejno
  3. Kopirajte ali prenesite
ali datoteko preprosto povlecite sem

Jedro težave: vsak ukaz, drugo kodiranje

V Windows PowerShellu 5.1 ima skoraj vsak ukaz svoje privzeto kodiranje: Get-Content bere datoteke brez BOM-a kot ANSI – v slovenskem Windowsu je to Windows-1250 –, Out-File in > pišeta UTF-16, Set-Content piše ANSI, Export-Csv pa ASCII. PowerShell 7 je to poenotil in povsod uporablja UTF-8 brez BOM-a.

Datoteka UTF-8, prebrana z Get-Content v PowerShellu 5.1

Prej

Uporabnik;Oddelek;Pisarna
Črt Žagar;Prodaja;Žalec
Nataša Čebron;Nabava;Kranj

Potem

Uporabnik;Oddelek;Pisarna
Črt Žagar;Prodaja;Žalec
Nataša Čebron;Nabava;Kranj

Pravilno branje in pisanje datotek

  • Get-Content podatki.csv -Encoding UTF8 pravilno prebere datoteke UTF-8 tudi brez BOM-a.
  • Set-Content, Out-File in Add-Content pišejo UTF-8 z -Encoding UTF8 – v 5.1 vedno z BOM-om.
  • Export-Csv podatki.csv -Encoding UTF8 -NoTypeInformation namesto privzetega ASCII, ki šumnike nadomesti z ?.
  • Za vse ukaze naenkrat: $PSDefaultParameterValues['*:Encoding'] = 'utf8' na začetku skripte.

Spletne zahteve: Invoke-RestMethod in Invoke-WebRequest

Če strežnik v glavi Content-Type ne navede nabora znakov, Windows PowerShell 5.1 odgovor dekodira kot ISO-8859-1. Odgovori UTF-8 potem vsebujejo napake, kot je ÄŤ. Rešitev: odgovor pridobite kot bajte in ga dekodirajte sami, npr. tako: [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).

Skriptne datoteke s posebnimi znaki

Če skripto shranite kot UTF-8 brez BOM-a, jo Windows PowerShell 5.1 bere kot ANSI. Znaki v nizih, kot je Write-Host "Žalec", se potem pokvarijo. Datoteke .ps1 shranjujte kot UTF-8 z BOM-om – v VS Code prek kodiranja v vrstici stanja, v Notepad++ prek menija Encoding → UTF-8-BOM.

Konzola

Če samo okno konzole kaže napačne znake, je datoteka pogosto v redu – konzola bere UTF-8 kot DOS-ovo kodno stran (v srednjeevropskem Windowsu 852). Izhod preklopite z [Console]::OutputEncoding = [Text.Encoding]::UTF8. Za izhod, ki ga posredujete zunanjim programom, nastavite še $OutputEncoding = [Text.Encoding]::UTF8.

Če je bila datoteka že zapisana pokvarjena, jo povlecite v polje zgoraj: Mojibuster popravi ÄŤ in podobne napake ter datoteke ANSI (Windows-1250) pretvori v UTF-8. Če datoteka že vsebuje vprašaje, je besedilo izgubljeno. Več o pojavu na strani kaj je mojibake.

Pogosta vprašanja

Katero različico PowerShella imam?

Pokaže jo $PSVersionTable.PSVersion. 5.1 je Windows PowerShell, vgrajen v Windows; od 7 naprej se imenuje preprosto PowerShell in privzeto uporablja UTF-8.

Zakaj Excel narobe odpre moj CSV iz PowerShella?

PowerShell 7 piše UTF-8 brez BOM-a, česar Excel ne prepozna. Uporabite -Encoding utf8BOM ali datoteko shranite z BOM-om v Mojibusterju. Več na strani o CSV-ju in šumnikih v Excelu.

Ali potrebujem chcp 65001?

Samo za programe, ki sledijo kodni strani konzole. Znotraj PowerShella zadošča [Console]::OutputEncoding.

Več navodil