Почему перенаправление powershell >> меняет форматирование текстового содержимого? - PullRequest
3 голосов
/ 09 июля 2019

Я хочу использовать приложение перенаправления >> или write> для записи в текстовый файл, но когда я это делаю, я получаю странный формат "\ x00a \ x00p ..." .

Я успешно использую set-content и add-content, почему они работают должным образом, а не операторы >> и> перенаправления?

Отображение вывода с использованием Powershell 'cat' и простой печати на Python.

rocket_brain> new-item test.txt
rocket_brain> "appended using add-content" | add-content test.txt
rocket_brain> cat test.txt

 appended using add-content

но тогда, если я использую перенаправление append >>

rocket_brain> "appended using redirect" >> test.txt
rocket_brain> cat test.txt

 appended using add-content
 a p p e n d e d   u s i n g   r e d i r e c t

Простой скрипт на python: read_test.py

with open("test.txt", "r") as file:   # open test.txt in readmode
    data = file.readlines()           # append each line to the list data
    print(data)                       # output list with each input line as an item

Используя read_test.py, я вижу разницу в форматировании

rocket_brain> python read_test.txt
 ['appended using add-content\n', 'a\x00p\x00p\x00e\x00n\x00d\x00e\x00d\x00 \x00u\x00s\x00i\x00n\x00g\x00 \x00r\x00e\x00d\x00i\x00r\x00e\x00c\x00t\x00\r\x00\n', '\x00']

ПРИМЕЧАНИЕ. Если я использую только команду redirect append >> (или write>) без предварительного использования add-content, вывод cat выглядит нормально (вместо разнесения), но тогда я получу / x00p формат для каждой строки при использовании скрипта python (включая любую команду add-content после запуска с> операторами). Открыв файл в блокноте (или VS и т. Д.), Текст всегда выглядит как положено. Использование >> или> в cmd (вместо PS) также сохраняет текст в ожидаемом формате ascii.

ссылки по теме операторы перенаправления cmd , Операторы перенаправления PS

Ответы [ 3 ]

6 голосов
/ 09 июля 2019

Примечание. В конечном итоге проблема заключается в том, что в Windows PowerShell разные командлеты / операторы используют разные кодировки по умолчанию.Эта проблема была решена в PowerShell Core , где постоянно используется UTF-8 без спецификации.


  • >> применяется вслепую *Кодировка 1012 * по умолчанию при добавлении к существующему файлу (в действительности > ведет себя как Out-File и >> как Out-File -Append), которая в Windows PowerShell является кодировкойс именем Unicode, то есть UTF-16LE , где большинство символов кодируются в виде 2-байтовых последовательностей, даже в диапазоне ASCII;последний имеет 0x0 (NUL) в качестве старшего байта.

    • Следовательно, , если существующее содержимое целевого файла не использует ту же кодировку, вы получите смесь различных кодировок , что и произошло в вашем случае. [1]
  • В то время как Add-Content,напротив, пытается определить существующую кодировку файла Еще раз спасибо, js2010 . , вы использовали его в пустом файле, в этом случае *Применяется кодировка по умолчанию 1047 * , которая в Windows PowerShell является кодировкой с именем Default, которая относится к активной кодовой странице ANSI вашей системы .

    • Поэтому, чтобы соответствовать однобайтовой кодировке ANSI, первоначально созданной вашим вызовом Add-Content при добавлении дополнительного содержимого, используйте Out-File -Append -Encoding Default вместо >> или простопродолжайте использовать Add-Content.

      • В качестве альтернативы, выберите другую кодировку с Add-Content -Encoding ... и сопоставьте ее в вызове Out-File -Append;UTF-8, как правило, является лучшим выбором, хотя учтите, что когда вы создаете файл UTF-8 в Windows PowerShell, он начинается с спецификации (псевдобайтовой метки, идентифицирующей файл как UTF-8, на Unix-подобных платформах).как правило, не ожидают).

      • В PowerShell v5.1 + вы также можете изменить глобальную кодировку по умолчанию , в том числе для > и >> (чтоне возможно в более ранних версиях).Например, чтобы перейти на UTF-8, используйте:
        $PSDefaultParameterValues['*:Encoding']='UTF8'


Помимо различных кодировок по умолчанию(в Windows PowerShell) важно отметить, что Set-Content / Add-Content, с одной стороны, и > / >> / Out-File [-Append], с другой, ведут себя принципиально по-разному, если нестрока input :

Короче говоря: первые применяют простое .ToString() -форматирование к входным объектам, тогда как последние выполняют такое же форматирование вывода, как и в консоли - см. этот ответ для подробностей.


[1] Из-за начального содержимого, установленного Add-Content, Windows PowerShell интерпретирует файл как кодированный ANSI (по умолчанию при отсутствииспецификации), где каждый байт является собственным символом.Содержимое UTF-16, добавленное позже, поэтому также интерпретируется, как если бы оно было ANSI, поэтому байты 0x0 обрабатываются как самостоятельные символы, которые выводятся на консоль как пробелы.

1 голос
/ 09 июля 2019

>> или out-file -append добавит текст в Unicode по умолчанию, даже если файл не является Unicode.Add-content сначала проверит кодировку файла и сопоставит его.По умолчанию для add-content или set-content используется ANSI-кодирование.Я бы никогда не использовал>, >> или out-file.

Просмотр чего-то с пробелами - это раздача, что это юникод.Unicode обычно имеет $ null между буквами.Если вы сбросите гекс, как в emacs esc-x hexl-mode, вы можете увидеть его.Boms - это 2 или 3 шестнадцатеричных символа в начале файла.

a p p e n d e d   u s i n g   r e d i r e c t

Это правильно сконструированный текстовый файл Unicode, скопированный и вставленный из hexl-режима emacs.FFF - это бомбаПосле каждого символа 00. В конце 0d и 0a, возврат каретки и перевод строки.Такие вещи меня интересуют.Некоторые утилиты Windows могут создать текстовый файл в формате Unicode без BOM (icacls / save).Затем, если вы наберете файл, между буквами появятся пробелы.

00000000: fffe 6100 7000 7000 6500 6e00 6400 6500  ..a.p.p.e.n.d.e.
00000010: 6400 2000 7500 7300 6900 6e00 6700 2000  d. .u.s.i.n.g. .
00000020: 7200 6500 6400 6900 7200 6500 6300 7400  r.e.d.i.r.e.c.t.
00000030: 0d00 0a00                                ....
1 голос
/ 09 июля 2019

>> и > перенаправляет консоль выход. Так что я предполагаю, что это иногда будет включать некоторые странные символы >> и > более тесно связаны с командлетом Out-File.

add-content не перенаправляет вывод консоли в файл, он только записывает значения, которые вы ему предоставляете (например, переменную или объект конвейера)

about_redirection

...