Кодировка текста от Linux до Windows - PullRequest
1 голос
/ 17 марта 2020

Главный вопрос, который у меня возникает, - как получить текстовый файл, который есть в Linux, для правильного отображения в PowerShell.

В Linux у меня есть текстовые файлы с некоторыми специальными символами, и фактически Блокнот отображает текстовый файл в точности так, как он отображается в Linux:

Notepad output

К сожалению, моя программа печатает на моем Linux терминале, и поэтому мне нужен такой же вывод на моем Windows терминале. В других ответах я видел, что

  1. Мне нужно использовать шрифт TrueType, поэтому я использую Lucidia Console
  2. на своем устройстве Linux, кодировка UTF-8. Согласно каждому ответу, который я могу найти в Интернете, CHCP 65001 переключает кодовую страницу в PowerShell на UTF-8
  3. Windows. Powershell лучше оснащен для отображения содержимого, поэтому, хотя я и пытался использовать командную строку, я теперь работает в PowerShell.

Используя CHCP 65001, а затем набрав

more my_file.txt

, вы увидите следующее:

result from more command

при использовании

Get-Content -Encoding UTF8 my_file.txt

выходов:

result from get-content

Ни один из этих результатов не является достаточно хорошим, но я на самом деле обеспокоен что Get-Content здесь делает что-то другое. Код, который я передаю на windows, написан на бесплатном Pascal, а на бесплатном Pascal я могу предоставить кодовую страницу UTF-8, но это все. Таким образом, хотя Get-Content - хорошая команда для меня, чтобы проверить, способен ли PowerShell выдавать желаемый результат, я не могу использовать его. В Pascal вывод (который записывается на дисплей PowerShell) выглядит как:

Pascal Display

Что также плохо, эти линии должны соединяться потому что они делают в Linux (и, очевидно, некоторые символы интерпретируются так же, как?). Однако это может быть проблемой с кодовой страницей, выбранной в Pascal, что будет следующим шагом.

Мой вопрос сейчас заключается в том, как мне получить Windows Powershell, чтобы по умолчанию отображать текстовый файл, как показано в версии блокнота. Для меня не практично везде запускать Get-Content в моем коде, поэтому, хотя этот результат выглядит более многообещающим, я не могу следовать этому.

В качестве дополнительного вопроса, поскольку я нигде не мог найти его в Интернете, каковы основные игроки здесь, когда дело доходит до отображения контента, потому что это явно большая история, чем просто кодирование. Почему команды «more» и «Get-Content» отображают разные результаты? И почему «Get-Content» не может прочитать весь контент? Я предполагал, что UTF-8 был универсальным стандартом, и программы, которые могут читать UTF-8, могли бы по крайней мере фактически прочитать все символы, но все они читают это по-разному.

В качестве текста введите:

    ╭─────╮
    │     │
  ╭─│───╮ │
  │ │   │ │
  │ │ ╭─│───╮
  │ │ │ │ │ │
╭─│───│─╯ │ │
│ │ │ │   │ │
│ │ ╰─╯   │ │
│ │       │ │
│ ╰───────│─╯
│         │
╰─────────╯

В ответ на ответ, опубликованный ниже, я вижу, что

more my_file.txt

производит

more command output using OutputEncoding

при использовании

$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = 
  New-Object System.Text.UTF8Encoding 

1 Ответ

3 голосов
/ 17 марта 2020
  • Убедитесь, что ваш текстовый файл в кодировке UTF-8 имеет спецификацию - в противном случае ваш файл будет неверно истолкован как Windows PowerShell как кодируемый на основе активной кодовой страницы ANSI системы (тогда как PowerShell [Core] 6+ теперь, к счастью, постоянно использует UTF-8 при отсутствии спецификации).

    • В качестве альтернативы используйте Get-Content -Encoding Utf8 my_file.txt, чтобы явно указать кодировку файла.

    • Подробное обсуждение кодировки символов в Windows PowerShell и PowerShell [Core] см. В this ответ .

  • Для вывода из внешних программ для правильного захвата в переменной или для правильного перенаправления в файл , вам необходимо установить [Console]::OutputEncoding на кодировку символов, которую данная программа использует на выходе (для простой печати на дисплей это может быть необязательным, однако):

    • Если кодовая страница 65001 (UTF-8) действует , и ваша программа учитывает, что , вам нужно будет установить [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding; см. ниже, чтобы убедиться, что 65001 действительно действует, учитывая, что chcp 65001 изнутри PowerShell не эффективно.

    • Вы упомянули Free Pascal, чья поддержка Unicode описана здесь .
      Однако ваш снимок экрана показывает, что ваша программа Free Pascal выводит , а не UTF-8 потому что закругленные угловые символы были перекодированы в ? символов (что предполагает перекодирование с потерями в кодовую страницу OEM системы, где эти символы отсутствуют).

    • Поэтому, чтобы решить вашу проблему , вы должны убедиться, что ваша бесплатная Pascal программа либо безоговорочно выводит UTF-8, либо поддерживает активное кодовая страница (согласно сообщению chcp), при условии, что вы сначала установили ее на 65001 (кодовая страница UTF-8; см. ниже).

  • Выберите шрифт, который может отображать закругленные углы символов Unicode (например, (U+256D) в окно вашей консоли; Windows шрифт PowerShell по умолчанию, Lucinda Console, может , а не (он отображает enter image description here, как показано в вашем вопросе), но Consolas, для экземпляр (который PowerShell [Core] 6+ использует по умолчанию), может .


Использование кодировки UTF-8 с внешним программы последовательно :

Примечание :

  • Приведенная ниже команда не является необходимой и не оказывает никакого влияния на PowerShell команды, такие как Get-Content cmdlet.

  • Некоторые устаревшие консольные приложения , в частности more.com (которые Windows PowerShell включаются в more функцию ) - принципиально не поддерживает Unicode , только устаревшие кодовые страницы OEM. [*]

Согласно каждому ответу, который я могу найти в Интернете, CHCP 65001 переключает кодовую страницу в PowerShell на UTF-8

chcp 65001 не работает не , если работает из в PowerShell , потому что. NET кэширует значение [Console]::OutputEncoding при запуске сеанса PowerShell с кодовой страницей, которая действовала в то время.

Вместо этого вы можете использовать Следующее, чтобы полностью заставить консольное окно работать с UTF-8 (которое также неявно делает chcp report 65001 впоследствии):

$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding =
                    New-Object System.Text.UTF8Encoding

Это заставляет PowerShell интерпретировать вывод внешней программы как UTF-8, а также кодирует данные, которые отправляет во внешнюю программу как UTF-8 (благодаря переменной предпочтения $OutputEncoding).

* 11 61 * См. этот ответ для получения дополнительной информации.

[*] С действующей кодовой страницей UTF-8 65001 more тихо пропускает строки , которые содержат хотя бы один символ Unicode, который не может быть сопоставлен с OEM-кодом системы страница (любой символ, отсутствующий в однобайтовой кодовой странице OEM системы, который может представлять только 256 символов), который в этом случае применяется к строкам, содержащим символы с закругленными углами, например (BOX DRAWINGS LIGHT AR C ВНИЗ И ПРАВО, U+256D).

...