Примечание . Следующее относится к Windows PowerShell .
См. Следующий раздел для кросс-платформенной версии PowerShell Core (v6 +) .
В PSv5.1 или выше , где >и >>являются фактически псевдонимами Out-File, вы можете установить кодировку по умолчанию для >/ >>/ с Out-Fileпомощью $PSDefaultParameterValuesпеременной предпочтений :
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
В PSv5.0 или ниже вы не можете изменить кодировку для >/>> , но в PSv3 или выше описанный выше метод действительно работает для явных вызововOut-File .
( $PSDefaultParameterValuesПеременная предпочтений была введена в PSv3.0).
На PSv3.0 или выше , если вы хотите установить по умолчанию кодировку для всех командлетов , которые поддерживают
в -Encodingпараметр (который в PSv5.1 + включает в себя >и >>), используйте:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
Если вы поместите эту команду в свои$PROFILE командлеты, такие как Out-FileиSet-Content , по умолчанию будут использовать кодировку UTF-8, но обратите внимание, что это делает ее глобальным параметром сеанса , который повлияет на все команды / сценарии, которые явно не указывают кодировку.
Точно так же не забудьте включить такие команды в свои сценарии или модули, которые вы хотите вести таким же образом , чтобы они действительно вели себя одинаково, даже когда их запускает другой пользователь или другая машина.
Предостережение : ** PowerShell, начиная с версии 5.1 , неизменно создает файлы UTF-8 _с (псевдо) спецификацией _ ** , что является обычным явлением только в мире Windows - утилиты на основе Unix не распознают эту спецификацию (см. Внизу); см. этот пост для обходных путей, которые создают файлы UTF-8 без спецификации.
Для резюме дико непоследовательного поведения кодирования символов по умолчанию во многих стандартных командлетов Windows PowerShell см нижнюю секцию.
Автоматическая $OutputEncodingпеременная не связана и применяется только к тому, как PowerShell взаимодействует с внешними программами (какую кодировку использует PowerShell при отправке им строк) - она не имеет ничего общего с кодировкой, которую операторы перенаправления вывода и командлеты PowerShell используют для сохранения в файлы.
Дополнительное чтение: кроссплатформенная перспектива: PowerShell Core :
PowerShell теперь является кроссплатформенным , благодаря своей редакции PowerShell Core , чья кодировка - разумно - по умолчанию использует UTF-8 без спецификации , что соответствует Unix-подобным платформам.
Это означает , что исходный код-файлы без спецификации предполагается UTF-8, и с помощью >/ Out-File/ по Set-Contentумолчанию в спецификацию менее UTF-8; явное использование utf8 -Encodingаргумента также создает UTF-8 без спецификации , но вы можете выбрать создание файлов с псевдо-спецификацией со utf8bomзначением.
Если вы создаете сценарии PowerShell с помощью редактора на Unix-подобной платформе, а в настоящее время даже в Windows с кросс-платформенными редакторами, такими как Visual Studio Code и Sublime Text, полученный *.ps1файл обычно не будет иметь псевдо-спецификации UTF-8:
- Это отлично работает в PowerShell Core .
- Он может сломаться в Windows PowerShell , если файл содержит символы, отличные от ASCII; если вам действительно нужно использовать символы, отличные от ASCII, в ваших скриптах, сохраните их как UTF-8 с BOM .
Без спецификации Windows PowerShell (неверно) интерпретирует ваш сценарий как закодированный в устаревшей кодовой странице «ANSI» (определяемой языковым стандартом системы для приложений, предшествующих Unicode; например, Windows-1252 в системах на английском языке).
С другой стороны , файлы , которые делают имеют UTF-8 псевдо-BOM может быть проблематичным , на Unix-подобных платформах, так как они вызывают Unix утилит , таких как cat, sedи awk- и даже некоторые редакторы , такие как gedit- чтобы передать псевдо-BOM через , т.е. рассматривать это как данные .
- Это не всегда может быть проблемой, но определенно может быть, например, когда вы пытаетесь прочитать файл в строке
bash, скажем, text=$(cat file)или text=$(<file)- результирующая переменная будет содержать псевдо-спецификацию в качестве первых 3 байтов.
Несогласованное поведение кодировки по умолчанию в Windows PowerShell :
К сожалению, кодировка символов по умолчанию, используемая в Windows PowerShell, очень непоследовательна; Кросс-платформенная версия PowerShell Core , как обсуждалось в предыдущем разделе, похвально положила этому конец.
Заметка:
Нижеследующее не претендует на охват всех стандартных командлетов.
Поиск в Google имен командлетов для поиска их тем справки теперь по умолчанию показывает версию тем PowerShell Core ; используйте раскрывающийся список версий над списком тем слева, чтобы переключиться на версию Windows PowerShell .
На момент написания этой статьи в документации часто неверно утверждается, что ASCII является кодировкой по умолчанию в Windows PowerShell - см. Эту проблему с документацией GitHub .
Командлеты, которые пишут :
Out-Fileи >/ >>создать "Unicode" - UTF-16LE - файлы по умолчанию - в которых каждый символ диапазона ASCII (тоже) представлен двумя байтами, что заметно отличается от Set-Content/ Add-Content(см. следующий пункт); New-ModuleManifestа Export-CliXmlтакже создавать файлы UTF-16LE.
Set-Content(и Add-Contentесли файл еще не существует / пуст) использует кодировку ANSI (кодировку, заданную устаревшей кодовой страницей ANSI активного языкового стандарта, которую вызывает PowerShell Default).
Export-Csvдействительно создает файлы ASCII, как -Appendописано в документации, но см. примечания ниже.
Export-PSSession по умолчанию создает файлы UTF-8 с спецификацией.
New-Item -Type File -Value в настоящее время создает UTF-8 без спецификации (!).
В Send-MailMessageразделе справки также утверждается, что по умолчанию используется кодировка ASCII - я лично не проверял это утверждение.
Start-Transcript неизменно создает файлы UTF-8 с BOM, но см. примечания -Appendниже.
Re команды, которые добавляются в существующий файл:
>>/ Out-File -AppendНе делать не попытки соответствовать кодировке файла существующего контента . То есть они вслепую применяют свою кодировку по умолчанию, если не указано иное -Encoding, что невозможно >>(за исключением косвенного в PSv5.1 +, через $PSDefaultParameterValues, как показано выше). Вкратце: вы должны знать кодировку содержимого существующего файла и добавлять его, используя ту же кодировку.
Add-Contentявляется похвальным исключением: при отсутствии явного -Encodingаргумента он обнаруживает существующую кодировку и автоматически применяет ее к новому контенту. Спасибо, js2010 . Обратите внимание, что в Windows PowerShell это означает, что применяется кодировка ANSI, если существующее содержимое не имеет спецификации, тогда как в PowerShell Core используется кодировка UTF-8.
Это несоответствие между Out-File -Append/ >>и Add-Content, которое также влияет на PowerShell Core , обсуждается в этом выпуске GitHub .
Export-Csv -Append частично соответствует существующей кодировке: он слепо добавляет UTF-8, если кодировка существующего файла является любой из ASCII / UTF-8 / ANSI, но правильно соответствует UTF-16LE и UTF-16BE.
Другими словами: при отсутствии спецификации Export-Csv -Appendпредполагается , что используется UTF-8, тогда как Add-Contentпредполагается, что ANSI.
Start-Transcript -Append частично соответствует существующей кодировке: она правильно соответствует кодировкам с BOM , но по умолчанию используется кодировка ASCII с потенциально потерями при ее отсутствии.
Командлеты, которые читают (то есть кодировку, используемую при отсутствии спецификации ):
Get-Contentи по Import-PowerShellDataFileумолчанию используется ANSI ( Default), что согласуется с Set-Content.
ANSI - это также то, что по умолчанию использует сам движок PowerShell при чтении исходного кода из файлов.
В отличие от этого Import-Csv, Import-CliXmlи Select-Stringпредположим , UTF-8 в отсутствие спецификации.
>/>>стали эффективными псевдонимами дляOut-File5.1?