Примечание . Следующее относится к 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-File
5.1?