Powershell Format-Hex不显示行尾。为什么?

时间:2018-09-26 09:20:09

标签: powershell newline

我看不到行字节的任何结尾

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

有没有办法显示它们?

编辑:我还有一个文件显示相同的行为,并且该文件包含多行,如cat和notepad所确认。

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 :(得分:4)

如果您的意思是newline,则源字符串中没有一个。因此,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..

一个人也可以使用Powershell的反引号转义序列:"hello`r`n",其作用与附加[Environment]::NewLine相同,尽管只有后者是platform-aware

按评论的附录并进行编辑:

Powershell的Get-Content试图变得聪明。在大多数用例中, [需要引用] 中,从文本文件读取的数据不需要包含换行符。 Get-Content将填充一个数组,并且从文件中读取的每一行都将位于其自己的元素中。换行符有什么用?

将输出重定向到文件时,Powershell试图再次变得聪明。在大多数用例 [需要引用] 中,将文本添加到文本文件中意味着添加新的数据行。不追加现有行。实际上,有一个用于防止换行的单独开关:Add-Content -NoNewLine

此外,高级语言没有特定的字符串终止字符。当拥有一个字符串对象(如现代语言)时,字符串的长度将存储为字符串对象的属性。

在低级语言中,没有字符串的概念。只是一堆字符而已。怎么知道一个“字符串”在哪里开始和结束呢? Pascal的方法是在开头分配字节以包含实际的字符串数据长度。 C使用null-terminated strings。在DOS中,汇编程序使用dollar -terminated字符串。

答案 1 :(得分:2)

要补充vonPryz's helpful answer

tl;博士

Format-Hex .\x.txt

是在PowerShell中检查文件的原始字节内容的唯一方法。也就是说,您需要将输入文件路径作为直接参数(传递给隐含的-Path参数)。

一旦涉及到管道,根据定义,您正在处理的任何字符串都是 .NET字符串对象,这些对象本质上是UTF-16编码的。

echo "hello"实际上是Write-Output "hello",因为echoWrite-Output的内置别名,所以它会写一个单个字符串对象并按原样添加到管道中,并且由于它没有 embedded 换行符,因此Format-Hex不会显示一个。

有关更多信息,请继续阅读。


  • 通常,PowerShell不具有通过管道发送原始数据的概念:您始终在处理.NET类型的实例(对象)

  • 因此,当Format-Hex收到管道输入时,它永远不会看到原始字节流,它会在.NET 字符串上运行,它们本身就是UTF-16(“ Unicode”)字符串。

    • 只有-Encoding参数适用:它会在输出中 重新编码.NET字符串。

    • 默认情况下,Windows PowerShell中的输出编码为ASCII,而PowerShell Core中的输出编码为UTF-8。
      注意:在Windows PowerShell中,这意味着默认情况下,会以“有损”方式将7位ASCII范围之外的字符转码为文字?字符(其Unicode代码点和字节值为0x3F )。

    • -Raw开关仅与Windows PowerShell v5.1中的[int]System.Int32)类型的输入结合使用,并且已过时在PowerShell Core中完全无效。 [1]

  • echoWrite-Output cmdlet的内置别名,它接受 objects 写入管道。

    • 在您的情况下,该对象是单行字符串([string]System.String类型的对象),如上所述,它没有嵌入的换行符序列。
    • 顺便说一句:PowerShell 隐式输出未捕获的任何内容(分配给变量或重定向到其他位置),因此您的命令可以更惯用地编写为:

      "hello" | Format-Hex
      
  • 类似地,catGet-Content cmdlet的内置别名,该cmdlet读取文本文件的内容作为行数组,即一个字符串数组,其元素不是以换行符结尾。

    • 是将数组元素一个接一个地写入到管道中,Format-Hex分别渲染了 each 的字节-但是同样,没有任何换行符,因为输入对象(表示没有尾随换行符的行的数组元素)不包含任何对象。

    • 查看换行符的唯一方法是整体读取文件 ,这是-confusingly named--Raw开关的作用:

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

      尽管这确实反映了文件中的实际换行符,但请注意,出于上述原因,它不是文件的原始字节

      p>

[1]在撰写本文时,-Raw在v5.1 was never documented中的用途,也不是现在已经过时的事实。
简而言之:[int]类型的输入不一定由它包含的4个字节表示-如果值足够小,则使用单字节或双字节序列,建议使用更多紧凑的输出; -Raw将停用此功能并输出忠实的4字节表示形式。
在PS Core 中,您现在总是且始终不变地获得忠实的字节表示,而-Raw无效;有关完整故事,请参见this GitHub pull request