Uwaga: Poniższe informacje dotyczą programu Windows PowerShell .
Zobacz następną sekcję dotyczącą wieloplatformowej wersji programu PowerShell Core (v6 +) .
Na PSv5.1 lub nowszym , gdzie >
i >>
są efektywnymi aliasami Out-File
, możesz ustawić domyślne kodowanie dla >
/ >>
/ Out-File
poprzez $PSDefaultParameterValues
zmienną preferencji :
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
Na PSv5.0 lub poniżej , to nie można zmienić kodowanie >
/>>
, ale na PSv3 lub wyższy , powyższa technika czyni pracę dla jawnych wywołańOut-File
.
( $PSDefaultParameterValues
Zmienna preferencji została wprowadzona w PSv3.0).
Na PSv3.0 lub wyższy , jeśli chcesz ustawić domyślne kodowanie dla wszystkich apletów poleceń, które obsługują
to -Encoding
parametr (co obejmuje w PSv5.1 + >
i >>
), przeznaczenie:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
Jeśli umieścisz to polecenie w swoich poleceniach$PROFILE
cmdlet, takich jak Out-File
iSet-Content
będą domyślnie używać kodowania UTF-8, ale pamiętaj, że powoduje to ustawienie globalne sesji, które będzie miało wpływ na wszystkie polecenia / skrypty, które nie określają jawnie kodowania.
Podobnie, pamiętaj, aby w swoich skryptach lub modułach uwzględnić takie polecenia, które chcesz, aby zachowywały się w ten sam sposób , aby rzeczywiście zachowywały się tak samo, nawet jeśli są uruchamiane przez innego użytkownika lub inną maszynę.
Uwaga : PowerShell, począwszy od wersji 5.1, niezmiennie tworzy pliki UTF-8 _ z (pseudo) BOM_ , co jest zwyczajowe tylko w świecie Windows - narzędzia oparte na Uniksie nie rozpoznają tego BOM (patrz poniżej); zobacz ten post, aby poznać obejścia, które powodują tworzenie plików UTF-8 bez BOM.
Dla podsumowania szalenie niespójne domyślnego kodowania znaków zachowanie całej wiele standardowych poleceń cmdlet Windows PowerShell , zobacz dolną część.
$OutputEncoding
Zmienna automatyczna jest niepowiązana i dotyczy tylko sposobu, w jaki PowerShell komunikuje się z programami zewnętrznymi (jakiego kodowania używa PowerShell podczas wysyłania do nich ciągów) - nie ma nic wspólnego z kodowaniem używanym przez operatory przekierowania danych wyjściowych i polecenia cmdlet programu PowerShell do zapisywania w plikach.
Czytanie opcjonalne: perspektywa międzyplatformowa: PowerShell Core :
PowerShell jest teraz wieloplatformowy , za pośrednictwem wersji PowerShell Core , której kodowanie - rozsądnie - jest domyślnie ustawione na UTF-8 bez BOM , zgodnie z platformami typu Unix.
Oznacza to, że pliki kodu źródłowego bez BOM przyjmowane są za UTF-8, a przy użyciu >
/ Out-File
/ Set-Content
domyślnie BOM mniej UTF-8; jawne użycie utf8
-Encoding
argumentu również tworzy kod UTF-8 bez BOM , ale możesz zdecydować się na tworzenie plików z pseudo-BOM z utf8bom
wartością.
Jeśli tworzysz skrypty PowerShell za pomocą edytora na platformie uniksopodobnej, a obecnie nawet w systemie Windows z edytorami wieloplatformowymi, takimi jak Visual Studio Code i Sublime Text, wynikowy *.ps1
plik zazwyczaj nie będzie miał pseudo-BOM UTF-8:
- Działa to dobrze w programie PowerShell Core .
- Może się zepsuć w programie Windows PowerShell , jeśli plik zawiera znaki spoza zestawu ASCII; jeśli musisz używać znaków spoza zestawu ASCII w swoich skryptach, zapisz je jako UTF-8 z BOM .
Bez BOM program Windows PowerShell (mis) interpretuje skrypt jako zakodowany na starszej stronie kodowej „ANSI” (określonej przez ustawienia regionalne systemu dla aplikacji poprzedzających Unicode, np. Windows-1252 w systemach amerykańsko-angielskich).
Odwrotnie, pliki, które zrobienia mieć UTF-8 pseudo-BOM może być problematyczne na uniksowych platformach, ponieważ przyczyna narzędzi uniksowych takich jak cat
, sed
i awk
- a nawet niektórzy redaktorzy takie jak gedit
- aby zdać pseudo-LM dzięki , czyli traktować to jako dane .
- Nie zawsze może to stanowić problem, ale na pewno może tak być, na przykład przy próbie wczytania pliku do łańcucha
bash
z, powiedzmy, text=$(cat file)
lub text=$(<file)
- zmienna wynikowa będzie zawierała pseudo-BOM jako pierwsze 3 bajty.
Niespójne domyślne zachowanie kodowania w programie Windows PowerShell :
Niestety, domyślne kodowanie znaków używane w programie Windows PowerShell jest bardzo niespójne; wieloplatformowa edycja PowerShell Core , jak omówiono w poprzedniej sekcji, chwalebnie położyła to i zakończyła.
Uwaga:
Poniższe aspiracje nie obejmują wszystkich standardowych poleceń cmdlet.
Wyszukiwanie w Google nazw poleceń cmdlet w celu znalezienia ich tematów pomocy teraz pokazuje domyślnie wersję PowerShell Core tematów; użyj listy rozwijanej wersji nad listą tematów po lewej stronie, aby przełączyć się na wersję programu Windows PowerShell .
W chwili pisania tego tekstu dokumentacja często błędnie twierdzi, że ASCII jest domyślnym kodowaniem w programie Windows PowerShell - zobacz ten problem z dokumentacją GitHub .
Polecenia cmdlet, które piszą :
Out-File
i >
/ >>
utwórz „Unicode” - UTF-16LE - pliki domyślnie - w których każdy znak z zakresu ASCII (także) jest reprezentowany przez 2 bajty - co znacznie różni się od Set-Content
/ Add-Content
(patrz następny punkt); New-ModuleManifest
a Export-CliXml
także tworzyć pliki UTF-16LE.
Set-Content
(a Add-Content
jeśli plik jeszcze nie istnieje / jest pusty) używa kodowania ANSI (kodowanie określone przez starszą stronę kodową ANSI aktywnego ustawienia regionalnego, którą wywołuje program PowerShell Default
).
Export-Csv
rzeczywiście tworzy pliki ASCII, zgodnie z dokumentacją, ale zobacz uwagi -Append
poniżej.
Export-PSSession
domyślnie tworzy pliki UTF-8 z BOM.
New-Item -Type File -Value
obecnie tworzy bez BOM (!) UTF-8.
W Send-MailMessage
temacie pomocy podano również, że kodowanie ASCII jest domyślne - osobiście nie zweryfikowałem tego twierdzenia.
Start-Transcript
niezmiennie tworzy pliki UTF-8 z BOM, ale zobacz uwagi -Append
poniżej.
Ponownie polecenia dołączane do istniejącego pliku:
>>
/ Out-File -Append
Zrobić żadnej próby pasujące kodowanie pliku w istniejącej zawartości . Oznacza to, że ślepo stosują swoje domyślne kodowanie, chyba że poinstruowano inaczej -Encoding
, co nie jest opcją z >>
( z wyjątkiem pośrednio w PSv5.1 +, przez $PSDefaultParameterValues
, jak pokazano powyżej). W skrócie: musisz znać kodowanie zawartości istniejącego pliku i dołączyć przy użyciu tego samego kodowania.
Add-Content
jest chwalebnym wyjątkiem: w przypadku braku wyraźnego -Encoding
argumentu wykrywa istniejące kodowanie i automatycznie stosuje je do nowej treści. Dzięki, js2010 . Należy zauważyć, że w programie Windows PowerShell oznacza to, że jest to kodowanie ANSI, które jest stosowane, jeśli istniejąca zawartość nie ma BOM, podczas gdy w programie PowerShell Core jest to UTF-8.
Ta niespójność między Out-File -Append
/ >>
i Add-Content
, która ma również wpływ na program PowerShell Core , została omówiona w tym problemie w usłudze GitHub .
Export-Csv -Append
częściowo pasuje do istniejącego kodowania: ślepo dołącza UTF-8, jeśli kodowanie istniejącego pliku jest dowolne z ASCII / UTF-8 / ANSI, ale poprawnie pasuje do UTF-16LE i UTF-16BE.
Ujmując to inaczej: w przypadku braku BOM Export-Csv -Append
zakłada , że UTF-8 jest, podczas gdy Add-Content
zakłada ANSI.
Start-Transcript -Append
częściowo pasuje do istniejącego kodowania: prawidłowo dopasowuje kodowanie z BOM , ale domyślnie stosuje potencjalnie stratne kodowanie ASCII w przypadku jego braku.
Polecenia cmdlet, które odczytują (to znaczy kodowanie używane w przypadku braku BOM ):
Get-Content
i Import-PowerShellDataFile
domyślnie ANSI ( Default
), co jest zgodne z Set-Content
.
ANSI jest również tym, co sam aparat PowerShell domyślnie przyjmuje, gdy odczytuje kod źródłowy z plików.
Natomiast Import-Csv
, Import-CliXml
i Select-String
zakładamy, UTF-8 w przypadku braku BOM.
$PSDefaultParameterValues
chcp
raportów zależy wyłącznie[Console]::InputEncoding
. Nie możesz używaćchcp.com
z wnętrza PowerShell, ze względu na buforowanie kodowania .NET, ale możesz go używaćcmd.exe
, gdzie jest również skuteczny, jeśli później uruchomisz PowerShell z tego miejsca.Krótko mówiąc, użyj:
write-output "your text" | out-file -append -encoding utf8 "filename"
źródło