Powershell Format-Hex не показывает конец строки.Зачем? - PullRequest
0 голосов
/ 26 сентября 2018

Я не вижу конца строки байта

echo "hello" | Format-Hex -Raw -Encoding Ascii

есть ли способ показать их?

Редактировать: у меня также есть файл, который показывает то же поведение, и этотсодержит несколько строк, что подтверждается как cat, так и блокнотом.

PS C:\dev\cur CMR-27473_AMI_not_stopping_in_ecat_fault 97984 > cat .\x.txt
helo
helo2
PS C:\dev\cur CMR-27473_AMI_not_stopping_in_ecat_fault 97984 > Get-Content .\x.txt | Format-Hex -Raw


           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   68 65 6C 6F                                      helo


           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   68 65 6C 6F 32                                   helo2

Я вижу две записи.Но вместо этого я хочу видеть символы конца строки, то есть необработанное содержимое байтов.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

В дополнение к полезный ответ vonPryz :

tl; др :

Format-Hex .\x.txt

- единственный способпроверять необработанное содержимое файла в PowerShell;т. е. вам необходимо передать путь к входному файлу в качестве прямого аргумента (к подразумеваемому параметру -Path).

Если задействован конвейер , любые строкиВы по определению имеете дело с .NET string объектами, которые по своей природе кодируются в UTF-16.

echo "hello", что на самом деле Write-Output "hello", учитывая, что echoявляется встроенным псевдонимом для Write-Output, записывает однострочный объект в конвейер, как есть - и с учетом того, что у него нет внедренного newline, Format-Hex didn 't show one.

Подробнее читайте дальше.


  • Как правило, PowerShell не имеет понятия отправки необработанных данных через pipe : вы всегда имеете дело с экземплярами типов .NET (объектов) .

  • Поэтому, когда Format-Hex получает конвейерный ввод , он никогда не видит необработанные байтовые потоки , он работает на .NET строки , которые по своей природе являются строками UTF-16 ("Unicode").

    • Только тогда применяется параметр -Encoding: он перекодирует строки .NET на выходе .

    • По умолчанию кодировка выводаэто ASCII в Windows PowerShell и UTF-8 в PowerShell Core.
      Примечание. В Windows PowerShell это означает, что по умолчанию символы вне 7-битного диапазона ASCII транскодируются в режиме «с потерями» в литерал ?символ (чья кодовая точка Unicode и значение байта 0x3F).

    • Переключатель -Raw имеет смысл только в сочетании с [int] (System.Int32) - вводимый ввод вWindows PowerShell v5.1 и устарел в PowerShell Core, где он никак не влияет. [1]

  • echo - это встроенный псевдоним для командлета Write-Output, который принимает объекты для записи в конвейер.

    • В вашем случае этот объектоднострочная строка (объект типа [string] (System.String)), которая, как указано, не имеет встроенной последовательности новой строки.
    • В качестве отступления: PowerShell неявно выводит все, что не захвачено (присвоено переменной или перенаправлено в другое место), поэтому ваша команда может быть написана более идиоматически, как:

      "hello" | Format-Hex
      
  • Аналогично, cat - это встроенный псевдоним для командлета Get-Content, который считывает содержимое текстового файла в виде массива строк в массив строк, элементы которого не оканчиваются новой строкой.

    • Это элементы массива, которые записываются в конвейер один за другим,и Format-Hex визуализирует байты каждый отдельно - но, опять же, без каких-либо символов новой строки, потому что входные объекты (элементы массива, представляющие строки без завершающей строки) не содержат никаких.

    • Единственный способ увидеть новые строки - это прочитать файл в целом , что и делает - несколько с озадаченным названием - -Raw переключатель:

      Get-Content -Raw .\x.txt | Format-Hex
      

      Хотя теперь это отражает фактические символы новой строки, присутствующие вВ файле обратите внимание, что это , а не a необработанный байт представление файла по указанным причинам.


[1] На момент написания этой статьи цель -Raw в v5.1 никогда не была документирована , а также тот факт, что в настоящее время устарел.
Короче: [int] типизированный ввод был необязательно , представленный 4 байтами, которые он содержит - использовались однобайтовые или двухбайтовые последовательности, если значение было достаточно маленьким, в пользу более компактного вывода;-Raw деактивирует это и выведет точное 4-байтовое представление.
В PS Core вы теперь всегда и неизменно получаете точное байтовое представление, а -Raw имеетнет эффекта;для полной истории см. этот запрос на GitHub .

0 голосов
/ 26 сентября 2018

Если вы имеете в виду символ новой строки , в исходной строке его нет.Таким образом, Format-Hex не будет отображать единицу.

Windows использует CR LF-последовательность (0x0a, 0x0d) для новой строки.Чтобы увидеть управляющие символы, добавьте новую строку в строку.Таким образом,

"hello"+[environment]::newline | Format-Hex -Raw -Encoding Ascii


           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   68 65 6C 6C 6F 0D 0A                             hello..

Можно также использовать escape-последовательность Powershell: "hello`r`n" для того же эффекта, что и при добавлении [Environment]::NewLine, хотя только последний поддерживает платформу .

Приложение в соответствии с комментарием и редактирование:

Powershell Get-Content пытается быть умным.В большинстве случаев использования [необходима цитата] данные, считываемые из текстовых файлов, не обязательно должны содержать символы новой строки.Get-Content заполнит массив, и каждая строка, прочитанная из файла, будет иметь свой собственный элемент.Какой смысл использовать новую строку?

Когда вывод перенаправляется в файл, Powershell снова пытается проявить смекалку.В большинстве случаев использования [требуется цитирование] добавление текста в текстовый файл означает добавление новых строк данных.Не добавление существующей строки.На самом деле есть отдельный переключатель для предотвращения перевода строки: Add-Content -NoNewLine.

Более того, языки высокого уровня не имеют определенного символа завершения строки.Если у кого-то есть строковый объект, как в современных языках, длина строки сохраняется как атрибут строкового объекта.

В языках низкого уровня понятие строки отсутствует.Это просто набор персонажей, собранных вместе.Как тогда узнать, где начинается и заканчивается «строка»?Подход Паскаля заключается в выделении байта в начале, чтобы он содержал фактическую длину строки данных.C использует строки с нулевым символом в конце .В DOS ассемблерные программы использовали определяемые долларом строки.

...