Строковая переменная Powershell с кодировкой UTF-8 - PullRequest
1 голос
/ 17 октября 2019

Я проверил много связанных с этим вопросов, но не смог найти что-то, что решило бы мою проблему. По сути, я хочу сохранить строку в кодировке UTF-8 в переменной, а затем использовать эту строку в качестве имени файла.

Например, я пытаюсь загрузить видео с YouTube. Если мы печатаем заголовок видео, появляются неанглийские символы (ytd здесь youtube-dl):

./ytd https://www.youtube.com/watch?v=GWYndKw_zbw -e

Вывод: [LEEPLAY] 시티팝 입문 City Pop MIX (Playlist)

Но если я сохраню это в переменной и напечатаю, корейские символы игнорируются:

$vtitle= ./ytd https://www.youtube.com/watch?v=GWYndKw_zbw -e

$vtitle

Вывод: [LEEPLAY] City Pop MIX (Playlist)

Ответы [ 2 ]

1 голос
/ 18 октября 2019

Это работает для меня в ISE. Youtube-dl из ytdl-org.github.io. На самом деле ise не понадобится, но имя файла будет отображаться правильно только в чем-то вроде проводника.

# get title
# utf-16 has a bom, or use utf-8-sig, this program is python based
$a = .\youtube-dl -e https://www.youtube.com/watch?v=Qpy7N4oFQUQ --encoding utf-16
$a
Gacharic Spin - 赤裸ライアー教則映像(short ver.)TOMO-ZO編

Возможно, вам повезет с vscode (или osx / linux).

1 голос
/ 17 октября 2019

Когда PowerShell интерпретирует вывод из внешних программ (например, ytd в вашем случае), предполагает, что в выводе используется кодировка символов, отраженная в [Console]::OutputEncoding.

Примечание:

  • Интерпретация относится к случаям, когда PowerShell захватывает (например, $output = ...), реле (например, ... | Select-String ...) или перенаправляет (например, ... > output.txt) на выход внешней программы.

  • Напротив, печатая напрямуюна дисплей это не влияет, поскольку PowerShell не задействован (что объясняет, почему символы выглядели так, как ожидалось в вашей консоли, когда вывод ytd выводился непосредственно на нее).

Если кодировка, сообщаемая [Console]::OutputEncoding, не совпадает с кодировкой, используемой внешней программой, PowerShell неверно интерпретирует вывод.

Чтобы это исправить, необходимо(временно) установите [Console]::OutputEncoding] в соответствии с кодировкой, используемой внешней программой .

Например,давайте предположим, что исполняемый файл foo.exe выводит текст в кодировке UTF-8:

# Save the current encoding and switch to UTF-8.
$prev = [Console]::OutputEncoding
[Console]::OutputEncoding = [Text.Encoding]::Utf8

# PowerShell now interprets foo's output correctly as UTF-8-encoded.
# and $output will correctly contain CJK characters.
$output = foo https://example.org -e

# Restore the previous encoding.
[Console]::OutputEncoding = $prev

Важно :

  • Изменение[Console]::OutputEncoding в соответствии с кодировкой символов внешней программы в настоящее время не работает в PowerShell Core , по состоянию на 7.0.0-preview.4 и , скорее всего, будут исправлены вv7.0 - см. отчет об ошибке на GitHub ; Windows PowerShell не изменяется.

  • [Console]::OutputEncoding по умолчанию отражает кодировку, связанную с кодовой страницей OEM устаревшей языковой системы , о чем сообщает chcp (например, 437 в системах на английском и американском языках).


Имея конкретную программу под рукой, youtube-dl, js2010 обнаружил , что захватв переменной работает без лишних усилий, если вы передаете --encoding utf-16.

. Причина, по которой это работает, заключается в том, что результирующий выход в кодировке UTF16-LE имеет значение , которому предшествует спецификация (метка порядка байтов).

(Обратите внимание, что --encoding utf-8 не не работает, потому что youtube-dl затем не излучает спецификацию.)

Windows PowerShell способна обнаруживать и правильно декодировать текст в кодировке UTF-16LE и кодировке UTF-8 независимо от действующего [Console]::OutputEncoding] ЕСЛИ И ТОЛЬКО ЕСЛИ выходу предшествуетспецификация

Предостережения :

  • Это не работает в PowerShell Core (на любом изподдерживаемые платформы)

  • Даже в Windows PowerShell вы редко сможете воспользоваться этим неясным поведением, поскольку использование спецификации в выводе stdout равно нетипичный (обычно используется только в файлах ).

...