PowerShell'in varsayılan çıktı kodlamasını UTF-8 olarak değiştirme


105

Varsayılan olarak, bir komutun çıktısını bir dosyaya yönlendirdiğinizde veya PowerShell'de başka bir şeye yönlendirdiğinizde, kodlama UTF-16'dır ve bu kullanışlı değildir. UTF-8 olarak değiştirmek istiyorum.

>foo.txtSözdizimini ile değiştirerek duruma göre yapılabilir, | out-file foo.txt -encoding utf8ancak bunun her seferinde tekrarlanması gariptir.

Bir şeyleri PowerShell'de ayarlamanın kalıcı yolu onları yerleştirmektir \Users\me\Documents\WindowsPowerShell\profile.ps1; Bu dosyanın gerçekten başlangıçta yürütüldüğünü doğruladım.

Çıkış kodlamasının ayarlanabileceği söylendi $PSDefaultParameterValues = @{'Out-File:Encoding' = 'utf8'}ama bunu denedim ve hiçbir etkisi olmadı.

https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/ bahsediyor hangi $OutputEncodingalakalı olmalıdır sanki ilk bakışta görünüyor, ama sonra çıkış kodlanmış olan bahsediyor ASCII'de, aslında olan şey bu değil.

PowerShell'i UTF-8 kullanacak şekilde nasıl ayarlarsınız?

Yanıtlar:


163

Not: Aşağıdakiler Windows PowerShell için geçerlidir . Çapraz platform PowerShell Core (v6 +) sürümü
için sonraki bölüme bakın .

  • On PSv5.1 veya daha yüksek , >ve >>etkili şekilde üst rumuzudur Out-Fileyapabilirsiniz, varsayılan kodlamayı ayarlamak için >/ >>/ Out-Filearacılığıyla $PSDefaultParameterValuestercihi değişken :

    • $PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
  • On PSv5.0 veya altında , sen olamaz kodlamasını değiştirmek >/>> fakat, üzerinde PSv3 veya daha yüksek , yukarıdaki teknik yapar için açık çağrılar için çalışmalarınıOut-File .
    ( $PSDefaultParameterValuesTercih değişkeni PSv3.0'da tanıtıldı).

  • On PSv3.0 veya üstü , isterseniz için kodlama varsayılan ayarlamak bütün destekleyen cmdletler
    bir -Encodingparametreyi
    (PSv5.1 + 'da içerir >ve >>) kullanın:

    • $PSDefaultParameterValues['*:Encoding'] = 'utf8'

Eğer bu komutu yerleştirirseniz$PROFILE böyle, cmdlets olarak Out-FileveSet-Content bu bir hale getirir UTF-8 varsayılan olarak kodlamayı ancak not kullanacağı oturum küresel ayar açıkça bir kodlama belirtmeyen tüm komutlar / komut etkileyecektir.

Benzer şekilde, komut dosyalarınıza veya modüllerinize aynı şekilde davranmak istediğiniz bu tür komutları eklediğinizden emin olun , böylece başka bir kullanıcı veya farklı bir makine tarafından çalıştırıldıklarında bile aynı şekilde davranırlar.

Uyarı : ** PowerShell, v5.1'den itibaren, yalnızca Windows dünyasında alışılmış olan (sözde) BOM _ ** ile her zaman UTF-8 dosyaları oluşturur - Unix tabanlı yardımcı programlar bu BOM'u tanımaz (aşağıya bakın); bkz Bu yayını BOM-az UTF-8 dosyaları oluşturmak çözümler için.

Windows PowerShell standart cmdlet'lerinin çoğunda çılgınca tutarsız varsayılan karakter kodlama davranışının bir özeti için alt bölüme bakın.


Otomatik $OutputEncodingdeğişken ilgisizdir ve yalnızca PowerShell'in harici programlarla nasıl iletişim kurduğu için geçerlidir (PowerShell bunlara dizeler gönderirken hangi kodlamayı kullanır) - çıktı yeniden yönlendirme operatörlerinin ve PowerShell cmdlet'lerinin dosyalara kaydetmek için kullandıkları kodlamayla hiçbir ilgisi yoktur.


İsteğe bağlı okuma: Çapraz platform perspektifi: PowerShell Core :

PowerShell artık kodlaması - makul bir şekilde - varsayılan olarak Unix benzeri platformlarla uyumlu olarak BOM'suz UTF-8'e sahip olan PowerShell Core sürümü aracılığıyla çapraz platformdur.

  • Bu, BOM içermeyen kaynak kod dosyalarının UTF-8 olduğu varsayıldığı ve >/ Out-File/ Set-Contentdefaults kullanılarak BOM'suz UTF-8 olduğu anlamına gelir; açık kullanım utf8 -Encodingargüman da yaratır BOM-az UTF-8, ancak dosyaları oluşturmak için seçebilirler ile birlikte sözde BOM utf8bomdeğeri.

  • Eğer Unix benzeri ve günümüzde bile platformda bir bir editör ile PowerShell komut dosyaları oluşturursanız , Windows , Visual Studio Kanunu ve Sublime Text olarak çapraz platform editörleri ile, ortaya çıkan *.ps1dosyası genellikle edecek değil UTF-8 sözde BOM vardır:

    • Bu, PowerShell Core'da iyi çalışıyor .
    • Dosya ASCII olmayan karakterler içeriyorsa Windows PowerShell'de bozulabilir ; komut dosyalarınızda ASCII olmayan karakterler kullanmanız gerekiyorsa, bunları BOM ile UTF-8 olarak kaydedin .
      BOM olmadan, Windows PowerShell (yanlış) komut dosyanızı eski "ANSI" kod sayfasında kodlanmış olarak yorumlar (Unicode öncesi uygulamalar için sistem yerel ayarı tarafından belirlenir; örneğin, ABD İngilizcesi sistemlerde Windows-1252).
  • Tersine, dosyalar yapmak UTF-8 sözde BOM üzerinde sorunlu olabilir var Unix benzeri platformlar, onlar gibi Unix programları neden cat, sedve awk- ve bu şekilde hatta bazı editörler gedit- için aracılığıyla sözde BOM geçmesi yani, veri olarak ele almak için .

    • Bu olmayabilir her zaman bir sorun, ama kesinlikle böyle sen bir dize içine bir dosyayı okumaya çalıştığınızda gibi olabilir bashdiyelim ki, birlikte, text=$(cat file)ya text=$(<file)- sonuçlanan değişken ilk 3 byte olarak sözde BOM içerecektir.

Windows PowerShell'de tutarsız varsayılan kodlama davranışı :

Ne yazık ki, Windows PowerShell'de kullanılan varsayılan karakter kodlaması son derece tutarsızdır; önceki bölümde tartışıldığı gibi platformlar arası PowerShell Core sürümü bunu övgüye değer bir şekilde koydu ve sona erdirdi.

Not:

  • Aşağıdakiler tüm standart cmdlet'leri kapsamayı amaçlamaz.

  • Yardım konularını bulmanız için Googling cmdlet adları artık size varsayılan olarak konuların PowerShell Core sürümünü gösteriyor ; Windows PowerShell sürümüne geçmek için soldaki konular listesinin üzerindeki sürüm açılır listesini kullanın .

  • Bu yazı itibariyle, belgeler sıklıkla yanlış bir şekilde ASCII'nin Windows PowerShell'deki varsayılan kodlama olduğunu iddia ediyor - bu GitHub belgeleri sorununa bakın .


O Cmdlet'lerini yazma :

Out-Fileve >/ >>create "Unicode" - UTF-16LE - varsayılan olarak dosyalar - her ASCII aralığı karakteri (de) 2 bayt ile temsil edilir - bu, Set-Content/ ' den önemli ölçüde farklıdır Add-Content(sonraki noktaya bakın); New-ModuleManifestve Export-CliXmlayrıca UTF-16LE dosyaları oluşturun.

Set-Content(ve Add-Contentdosya henüz mevcut değilse / boşsa) ANSI kodlamasını (PowerShell'in çağırdığı etkin sistem yerel ayarının ANSI eski kod sayfası tarafından belirtilen kodlama) kullanır Default.

Export-Csvgerçekten de belgelendiği gibi ASCII dosyaları oluşturur, ancak -Appendaşağıdaki notlara bakın.

Export-PSSession varsayılan olarak BOM ile UTF-8 dosyaları oluşturur.

New-Item -Type File -Value şu anda BOM'suz (!) UTF-8 oluşturur.

Send-MailMessageYardım konusu da bu ASCII kodlama varsayılan olduğunu iddia - Ben şahsen istem olmadığı henüz doğrulanmamıştır.

Start-Transcript her zaman BOM ile UTF-8 dosyaları oluşturur , ancak -Appendaşağıdaki notlara bakın.

Mevcut bir dosyaya eklenen komutları yeniden :

>>/ Out-File -AppendYapmak hiç bir dosyanın kodlamasını maç için girişimde mevcut içerik . Diğer bir deyişle, aksi belirtilmedikçe varsayılan kodlamalarını körü körüne uygularlar -Encoding, bu seçenekle bir seçenek değildir >>( $PSDefaultParameterValuesyukarıda gösterildiği gibi PSv5.1 +, aracılığıyla dolaylı olarak hariç ). Kısacası, mevcut bir dosyanın içeriğinin kodlamasını bilmeli ve aynı kodlamayı kullanarak eklemelisiniz.

Add-Contentövgüye değer bir istisnadır: açık bir -Encodingargümanın yokluğunda , mevcut kodlamayı algılar ve bunu yeni içeriğe otomatik olarak uygular. Teşekkürler js2010 . Windows PowerShell'de bunun, mevcut içerikte BOM yoksa uygulanan ANSI kodlaması olduğu, PowerShell Core'da ise UTF-8 olduğu anlamına geldiğini unutmayın.

Bu tutarsızlık arasındaki Out-File -Append/ >>ve Add-Contentayrıca PowerShell etkiler, Çekirdek , tartışılan bu GitHub sorunu .

Export-Csv -Append mevcut kodlamayla kısmen eşleşir: Mevcut dosyanın kodlaması ASCII / UTF-8 / ANSI'den herhangi biri ise, ancak UTF-16LE ve UTF-16BE ile doğru şekilde eşleşiyorsa UTF- 8'i körü körüne ekler .
Farklı bir şekilde ifade etmek gerekirse: bir ürün reçetesinin yokluğunda, Export-Csv -AppendUTF-8'in olduğunu, ancak Add-ContentANSI olduğunu varsayar.

Start-Transcript -Append mevcut kodlamayla kısmen eşleşir: Kodlamaları BOM ile doğru şekilde eşleştirir , ancak varsayılan olarak, bir kodlama olmadığında potansiyel olarak kayıplı ASCII kodlamasına sahiptir.


Davranırlar oku (diğer bir deyişle, kullanılan kodlama BOM yokluğunda ):

Get-Contentve Import-PowerShellDataFilevarsayılan ANSI ( Default), ile tutarlıdır Set-Content.
ANSI ayrıca PowerShell motorunun dosyalardan kaynak kodunu okuduğunda varsayılan olarak belirlediği şeydir .

Buna karşılık, Import-Csv, Import-CliXmlve Select-StringUTF-8 BOM yokluğunda varsayalım.


Nasıl açıklayabilir >/ >>etkili takma ad haline geldi Out-File5.1'de?
Maximilian Burszley

@ TheIncorrigible1: Bana bunu işaret eden PetSerAl olabilir, ancak nerede ve nasıl olduğunu hatırlamıyorum. Windows PowerShell kapalı kaynaklıdır, ancak aynı yarı-diğer ad ilişkisi PowerShell Core için de geçerli olduğundan, onu ikincisinin kaynak kodunda bulabilmeniz gerekir.
mklement 0

2
Buna katılmıyorum @EliaWeiss, ancak bu özellikle Windows PowerShell ve sonunda PowerShell Core'da doğru şekilde aldılar .
mklement0

2
@Marc: VS Code ve diğer modern çapraz platform editörleri övgüye değer bir şekilde UTF-8'i varsayılan olarak kullanırlar, ancak bu, ANSI kodlu dosyaları yanlış yorumlayacakları anlamına gelir. Notepad kullanır buluşsal için tahmin kodlama. Önemli olan, bunun yalnızca bir tahmin olmasıdır , çünkü herhangi bir UTF-8 kodlu dosya aynı zamanda teknik olarak geçerli bir ANSI kodlu dosyadır (ancak tersi değildir). Windows'taki her şeyin Unix benzeri platformların yaptığı gibi bir BOM yokluğunda UTF-8'e varsayılan olarak ayarlanması harika olurdu, ancak durum böyle değil, özellikle Windows PowerShell'de değil, neyse ki şu anda PowerShell Core'da durum böyle.
mklement0

2
Mevcut değerinizi izlemek için, şunu yazmanız $PSDefaultParameterValues
Sandburg

3

Kısa olmak gerekirse, şunu kullanın:

write-output "your text" | out-file -append -encoding utf8 "filename"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.