2014-01-15 15 views
1

看看我想在那里做什么?自然,它不起作用。powershell:如何使用ls dirA,dirB -rec |组FileName,VersionInfo.ProductVersion | ft -auto ...?

我想在几个目录中获取文件名和版本信息(产品名称,版本)的表以及重复计数。

的一个问题是,我似乎不能到组对象cmdlet的结果内到达,所以下面也不起作用。

ls VisitRecord-1/Release,Dispo-1/Release -rec ` 
    | % {@{FileName=$_.Name; ProductName=$_.VersionInfo.ProductName; ProductVersion=$_.VersionInfo.ProductVersion } ` 
     | New-HashObject} ` 
    | group FileName,ProductName,ProductVersion ` 
    | % {@{Count=$_.Count; FileName=$_.Group.FileName}} 

因为$ _ Group.FileName似乎返回空(或空字符串)。

我错过了什么?有任何想法吗? (我正在运行版本2的PowerShell。)

谢谢。

回答

2

TL; DR:我要离开我原来的答复,因为它显示了解决方法和随后的讨论有助于理解到底发生了什么上。然而,最佳的解决方案就在最后。


原来的答案(工作,但不这样做的最佳方式)

这似乎是在PowerShell 2.0中的错误。我在3.0中试过你的代码,它工作正常(除了我用New-Object -Property而不是| New-HashObject,因为我没有安装这个扩展,对我来说这似乎是多余的)。

对于一些奇怪的原因,在2.0中,你不能读取任何被集团对象返回的GroupInfo对象的NoteProperty属性。但是,如果您使用选择对象,它将起作用。这种替换您的最后一行:

| %{@{Count=$_.Count; FileName=$_.Group | select -expand FileName}} 

在一个旁注,正如我上面提到的,我不知道我看到新HashObject推广的价值。该作品一样好,只使用原生的PowerShell(为你的代码的第二行和第三行的替代品):

| %{New-Object PSObject -Property @{FileName=$_.Name; ProductName=$_.VersionInfo.ProductName; ProductVersion=$_.VersionInfo.ProductVersion} ` 

UPDATE

解决方法上面的工作,但对于错误的原因。我认为$_.Group.FileName为试图读取的GroupInfo对象的NoteProperty,但阅读基思·希尔的评论后,我意识到,这是$ _这就是的GroupInfo对象,$ _。集团是一家作为集合的那个对象的属性。 OP的代码在PowerShell 3中工作的原因。0是该集合只有一个对象,因此枚举该集合的单个属性(FileName)将返回单个字符串而不是数组。

然而,它是一个集合实际上使解决方案更简单。只需添加一个[0].Group后检索的第一个(也是唯一一个)对象的集合中:

| % {@{Count=$_.Count; FileName=$_.Group[0].FileName}} 
+0

看起来不需要周围的$()。在看到Keith Hill的回答后,我尝试了没有它的版本,并且这也起作用。 –

+2

这不是一个错误。 PowerShell V3添加了成员​​枚举,这就是$ Collection.Property($ _。Group.Filename)在V3和更高版本中工作的原因。 –

+0

@凯特希尔啊,我明白你在说什么了。我忽略了他没有尝试读取** GroupInfo **对象本身的属性,因为** $ _ **是** GroupInfo **对象,并且** $ _。Group **是该属性的一个属性** GroupInfo **对象,它是一个集合。所以他的代码在PS 2.0中不起作用,因为他试图读取集合的成员属性,并且它仅在3.0中工作,因为集合恰好在每种​​情况下都只有一个对象。在那种情况下,我有一个更好的答案 - 只需在'.Group'后添加'[0]',这是唯一需要的修改。我会更新我的答案。 –

2

它在V4上按原样工作。您可能需要额外的foreach所V2及以下例如为:

ls VisitRecord-1/Release,Dispo-1/Release -rec ` 
    | % {@{FileName=$_.Name; ProductName=$_.VersionInfo.ProductName; ProductVersion=$_.VersionInfo.ProductVersion } ` 
    | New-HashObject} ` 
    | group FileName,ProductName,ProductVersion ` 
    | % {@{Count=$_.Count; FileName=$_.Group | %{$_.FileName}}} 
+0

是的,它也适用于这种方式,我只是测试它。我猜这是基本相同的想法... –

+0

http://www.codeplex.com/site/users/view/r_keith_hill,我想。 :) – JohnL4

+0

是的,那就是我。 –

0

前两个答案都非常优秀,非常感谢。希望我可以将它们标记为答案。回答我自己的问题,以便我可以删除一些代码,我认为我不能在评论中做。

我的解决方案(耶,吃午饭和他的动手):

ls VisitRecord-1/Release,Dispo-1/Release -rec ` 
    | % {@{FileName=$_.Name; ProductName=$_.VersionInfo.ProductName; ProductVersion=$_.VersionInfo.ProductVersion }} ` 
    | New-HashObject ` 
    | group FileName,ProductName,ProductVersion ` 
    | % {$grp = $_.Name -split ', '; @{Count=$_.Count; FileName=$grp[0]; ProductName=$grp[1]; ProductVersion=$grp[2]}} ` 
    | New-HashObject ` 
    | Select Count,FileName,ProductName,ProductVersion ` 
    | sort ProductName,FileName ` 
    | ft -auto 

不过似乎有点矫枉过正,但我​​就认为这是错误的解决方法。

我喜欢PSCX,但是我对当地PS和什么是PSCX感到困惑。我认为New-HashObject 的胜利可能是,因为它可以在其输入上生成一串哈希表并产生一个对象流。可能的性能增益?

无论如何,高兴地发现它是PS 2.0中的一个错误。我想这是一个足够好的理由来升级。 :)安装PS 3.0

重写命令行后


编辑:

ls VisitRecord-1/Release,Dispo-1/Release -rec ` 
    | % {@{FileName=$_.Name; ` 
      ProductName=$_.VersionInfo.ProductName; ` 
      ProductVersion=$_.VersionInfo.ProductVersion }} ` 
    | New-HashObject ` 
    | group FileName,ProductName,ProductVersion ` 
    | % {@{Count=$_.Count; ` 
      GroupCount=$_.Group.Count; ` 
      FileName=$_.Group[0].FileName; ` 
      ProductName=$_.Group[0].ProductName; ` 
      ProductVersion=$_.Group[0].ProductVersion}} ` 
    | New-HashObject ` 
    | select Count,GroupCount,FileName,ProductName,ProductVersion ` 
    | sort ProductName,FileName ` 
    | ft -auto 

加送GroupCount为了说明,添加了[0]到组的引用。也许这会让它在PS 2.0下工作,但现在还没有回头(对我来说)。 :)

(编辑:而这一切之后,上述不工作PS 2.0下,毕竟)

更多比你想要了解集团的对象:

ls VisitRecord-1/Release,Dispo-1/Release -rec ` 
    | % {@{FileName=$_.Name; ProductName=$_.VersionInfo.ProductName; ProductVersion=$_.VersionInfo.ProductVersion }} ` 
    | New-HashObject ` 
    | group FileName,ProductName,ProductVersion ` 
    | ? {($_.Count -gt 1) -and ($_.Group[0].ProductName -ne $Null)} ` 
    | select -first 1 ` 
    | fl 

Name : Infragistics4.Shared.v13.1.dll, Infragistics4.Shared, 13.1.20131.2060 
Count : 2 
Group : {@{ProductVersion=13.1.20131.2060; FileName=Infragistics4.Shared.v13.1.dll; ProductName=Infragistics4.Shared}, 
     @{ProductVersion=13.1.20131.2060; FileName=Infragistics4.Shared.v13.1.dll; ProductName=Infragistics4.Shared}} 
Values : {Infragistics4.Shared.v13.1.dll, Infragistics4.Shared, 13.1.20131.2060} 
+0

s/bug/lacking/:) – JohnL4