2014-01-15 41 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