"$xyz" 和 "Write-Host "$xyz"" 给出不同的输出
"$xyz" and "Write-Host "$xyz"" giving different output
我正在对一个位置(一个原始文件夹)中的所有文件进行哈希处理,并将哈希值写入一个变量,然后对另一个位置(一个目标文件夹)中的所有文件执行相同的操作:
$origin = Get-ChildItem .\Test1 | Get-FileHash | Format-Table -Property Hash -HideTableHeaders
$destination = Get-ChildItem .\Test2 | Get-FileHash | Format-Table -Property Hash -HideTableHeaders
然后我将它们与 Compare-Object 进行比较,如下所示:
Compare-Object $origin $destination
现在在我的测试中我故意有偏差,所以当上面的代码返回没有差异时我知道我有问题。
然后我发现如果我执行以下操作,哈希值将不存在:
PS> Write-Host "$origin"
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
但是,如果我只输入以下内容并按回车键,那么哈希值就会出现(就像我想要的那样):
PS> $origin
6B86B273FF34FCE19D6B804EFF5A3F5747ADA4EAA22F1D49C01E52DDB7875B4B
D4735E3A265E16EEE03F59718B9B5D03019C07D8B6C51F90DA3A666EEC13AB35
4E07408562BEDB8B60CE05C1DECFE3AD16B72230967DE01F640B7E4729B49FCE
我假设当我使用 Compare-Object
时,我的变量没有像我预期的那样呈现哈希值。
有谁知道这是怎么回事或者有什么建议吗?这用于确保文件从原始位置移动到目标位置(这是我正在处理的脚本中的一项检查)。我保留这个纯粹的 PowerShell,这意味着没有 xcopy
或 robocopy
.
重新使用 Format-Table
为 Compare-Object
创建输入集合:
仅将 Format-*
cmdlet 用于 显示格式;如果数据必须以编程方式处理.
,则切勿使用它们
Format-*
cmdlet 输出 格式化指令 ,而不是 数据 - 请参阅 this answer.
因此:
- 省略 来自输入集合定义命令的
Format-Table
调用:
$origin=Get-ChildItem .\Test1 | Get-FileHash
$destination=Get-ChildItem .\Test2 | Get-FileHash
- 然后将 属性的名称 传递给
Compare-Object
: 来比较对象
Compare-Object $origin $destination -Property Path, Hash
注意需要通过路径和哈希进行比较,以确保只比较同名文件。
顺便说一句:如果您没有指定-Property
,默认情况下对象将按它们的.ToString()
值进行比较——并且由于Get-FileHash
输出的 Microsoft.PowerShell.Commands.FileHashInfo
个实例只会字符串化为非常 类型的名称 (不管它们的特定 属性 值如何),不会发现任何差异。
至于 $origin
与 Write-Host $orgin
:
只是执行 $origin
隐含地就像执行 Write-Output $origin
- 它写入 成功输出流 (请参阅 about_Redirection),默认情况下 转到控制台。
- 进入控制台的成功输出 由 PowerShell 的 rich output-formatting system.
自动格式化
Write-Host
,相比之下,与有不同的目的 =27=]:
直接写到控制台[1],绕过 PowerShell 的成功输出流及其通常的格式。 其主要目的是将状态消息、交互式提示消息...写入显示器 - 而不是输出数据 .
Write-Host
本身应用输出格式,但仅通过简单.ToString()
stringification,这通常会产生无用的(仅键入名称)表示,就像您的情况一样。
有关 Write-Output
和 Write-Host
之间差异的更多信息,请参阅 this answer。
[1] 从技术上讲,从 PowerShell 版本 5 开始,Write-Host
输出通过 information 输出流(编号 6
), 但它的主要目的仍然是 写入显示器 而不是 输出数据 .
我正在对一个位置(一个原始文件夹)中的所有文件进行哈希处理,并将哈希值写入一个变量,然后对另一个位置(一个目标文件夹)中的所有文件执行相同的操作:
$origin = Get-ChildItem .\Test1 | Get-FileHash | Format-Table -Property Hash -HideTableHeaders
$destination = Get-ChildItem .\Test2 | Get-FileHash | Format-Table -Property Hash -HideTableHeaders
然后我将它们与 Compare-Object 进行比较,如下所示:
Compare-Object $origin $destination
现在在我的测试中我故意有偏差,所以当上面的代码返回没有差异时我知道我有问题。
然后我发现如果我执行以下操作,哈希值将不存在:
PS> Write-Host "$origin" Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
但是,如果我只输入以下内容并按回车键,那么哈希值就会出现(就像我想要的那样):
PS> $origin 6B86B273FF34FCE19D6B804EFF5A3F5747ADA4EAA22F1D49C01E52DDB7875B4B D4735E3A265E16EEE03F59718B9B5D03019C07D8B6C51F90DA3A666EEC13AB35 4E07408562BEDB8B60CE05C1DECFE3AD16B72230967DE01F640B7E4729B49FCE
我假设当我使用 Compare-Object
时,我的变量没有像我预期的那样呈现哈希值。
有谁知道这是怎么回事或者有什么建议吗?这用于确保文件从原始位置移动到目标位置(这是我正在处理的脚本中的一项检查)。我保留这个纯粹的 PowerShell,这意味着没有 xcopy
或 robocopy
.
重新使用 Format-Table
为 Compare-Object
创建输入集合:
仅将 Format-*
cmdlet 用于 显示格式;如果数据必须以编程方式处理.
Format-*
cmdlet 输出 格式化指令 ,而不是 数据 - 请参阅 this answer.
因此:
- 省略 来自输入集合定义命令的
Format-Table
调用:
$origin=Get-ChildItem .\Test1 | Get-FileHash
$destination=Get-ChildItem .\Test2 | Get-FileHash
- 然后将 属性的名称 传递给
Compare-Object
: 来比较对象
Compare-Object $origin $destination -Property Path, Hash
注意需要通过路径和哈希进行比较,以确保只比较同名文件。
顺便说一句:如果您没有指定-Property
,默认情况下对象将按它们的.ToString()
值进行比较——并且由于Get-FileHash
输出的 Microsoft.PowerShell.Commands.FileHashInfo
个实例只会字符串化为非常 类型的名称 (不管它们的特定 属性 值如何),不会发现任何差异。
至于 $origin
与 Write-Host $orgin
:
只是执行
$origin
隐含地就像执行Write-Output $origin
- 它写入 成功输出流 (请参阅 about_Redirection),默认情况下 转到控制台。- 进入控制台的成功输出 由 PowerShell 的 rich output-formatting system. 自动格式化
Write-Host
,相比之下,与有不同的目的 =27=]:直接写到控制台[1],绕过 PowerShell 的成功输出流及其通常的格式。 其主要目的是将状态消息、交互式提示消息...写入显示器 - 而不是输出数据 .
Write-Host
本身应用输出格式,但仅通过简单.ToString()
stringification,这通常会产生无用的(仅键入名称)表示,就像您的情况一样。
有关 Write-Output
和 Write-Host
之间差异的更多信息,请参阅 this answer。
[1] 从技术上讲,从 PowerShell 版本 5 开始,Write-Host
输出通过 information 输出流(编号 6
), 但它的主要目的仍然是 写入显示器 而不是 输出数据 .