Powershell:空文件总是生成(Compare-Object的输出)

这个问题最stream行的答案涉及以下Windows PowerShell代码(编辑修复一个错误):

$file1 = Get-Content C:\temp\file1.txt $file2 = Get-Content C:\temp\file2.txt $Diff = Compare-Object $File1 $File2 $LeftSide = ($Diff | Where-Object {$_.SideIndicator -eq '<='}).InputObject $LeftSide | Set-Content C:\temp\file3.txt 

我总是得到一个零字节文件作为输出,即使我删除$ Diff线。

为什么输出文件始终为空,如何解决?

Solutions Collecting From Web of "Powershell:空文件总是生成(Compare-Object的输出)"

正如他惯常所做的那样, 宠物服务提供了关于这个问题的评论中的关键指标(无意将其转化为答案):

成员枚举 – 在PSv3中引入了使用隐式枚举 单独访问集合项目的成员(属性或方法)的能力

成员枚举不仅具有表达性和方便性 ,而且比替代方法更快

一个简单的例子:

 > ((Get-Item /), (Get-Item $HOME)).Mode d--hs- # The value of (Get-Item /).Mode d----- # The value of (Get-Item $HOME).Mode 

将.Mode应用于(...) enclosed命令输出的集合将导致在集合中的每个项目上访问.Mode属性,并将结果值作为数组返回(常规PowerShell数组,类型为[System.Object[]] )。

这个方便的功能不可用 ,但是:

  • 如果你运行在PSv2 (绝对)
  • 如果集合本身具有指定名称的成员 ,则在这种情况下应用集合级别成员。

例如,即使在PSv3 +下面也不执行成员枚举:

 > ('abc', 'cdefg').Length # Try to report the string lengths 2 # !! The *array's* .Length property value (item count) is reported, not the items' 

在这种情况下 – 一般在PSv2中 – 需要一种不同的方法:

  • 使用foreach 语句的 最快选择是假设整个集合整体适合内存(这在使用成员枚举时是隐含的 )。
 > foreach ($s in 'abc', 'cdefg') { $s.Length } 3 5 
  • PSv4 +替代方案,使用集合运算符 .ForEach() ,也作为整体对集合进行操作:
 > ('abc', 'cdefg').ForEach('Length') 3 5 
  • 使用流水线 最慢,但有效的方法是:

使用ForEach-Object cmdlet ,如Burt Harris的有用答案 :

 > 'abc', 'cdefg' | ForEach-Object { $_.Length } 3 5 

对于属性(与方法相反), Select-Object -ExpandProperty是一个选项; 虽然它在概念上是清晰和简单的,但它看起来表现最差,尽管只比ForEach-Object方法稍差一些:

 > 'abc', 'cdefg' | Select-Object -ExpandProperty Length 3 5 

也许不是

 $LeftSide = ($Diff | Where-Object {$_.SideIndicator -eq '<='}).InputObject 

PowerShell 2可能更好地工作:

 $LeftSide = $Diff | Where-Object {$_.SideIndicator -eq '<='} | Foreach-object { $_.InputObject }