2011-12-19 40 views
3

我有一個目錄列表,它們的格式與版本號相同,並希望找到N個最舊的目錄並刪除它們。例如:在PowerShell中刪除最舊版本的目錄

/1.2.3.4 
/1.2.3.5 
/1.2.3.6 

我已經嘗試了幾件事情,但我似乎無法得到我需要去的地方。

我的第一次嘗試是這樣的:

ls directory | sort Name | select -first 5 | rm -r 

但是我不知道這是怎麼回事在所有情況下工作,因爲這將(我相信)做了自然排序。這總是會返回正確的結果嗎?

我的下一個想法是,我可以使用System.Version來做我的排序。所以我結束了這一點:

ls directory | %{[System.Version]$_.Name } | sort | select -first 5 | ??? 

的問題是,我不知道如何將目錄結果綁排序...什麼是做到這一點的最好方法是什麼?

gci \\directory產生

Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
d----  12/19/2011 5:19 PM   1.0.1052.54849 
d----  12/19/2011 5:29 PM   1.0.1053.54850 
d----  12/19/2011 5:36 PM   1.0.1054.54851 
d----  12/20/2011 2:11 PM   1.0.1056.54875 
d----  12/12/2011 10:39 AM   1.0.991.54625 
d----  12/12/2011 12:08 PM   1.0.992.54627 
d----  12/12/2011 12:22 PM   1.0.993.54628 
d----  12/12/2011 1:15 PM   1.0.994.54630 
d----  12/12/2011 2:45 PM   1.0.996.54636 
d----  12/12/2011 3:34 PM   1.0.997.54640 
d----  12/12/2011 3:48 PM   1.0.998.54641 

gci \\directory | Sort-Object { $_Name -as [Version] }產生

Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
d----  12/12/2011 1:15 PM   1.0.994.54630 
d----  12/12/2011 12:22 PM   1.0.993.54628 
d----  12/12/2011 2:45 PM   1.0.996.54636 
d----  12/12/2011 3:48 PM   1.0.998.54641 
d----  12/12/2011 3:34 PM   1.0.997.54640 
d----  12/12/2011 12:08 PM   1.0.992.54627 
d----  12/19/2011 5:29 PM   1.0.1053.54850 
d----  12/19/2011 5:19 PM   1.0.1052.54849 
d----  12/19/2011 5:36 PM   1.0.1054.54851 
d----  12/12/2011 10:39 AM   1.0.991.54625 
d----  12/20/2011 2:11 PM   1.0.1056.54875 

不要緊,這是一個網絡共享?我很困惑,爲什麼這不起作用...我做了一個快速的理智檢查,並在我在單元測試中創建的版本上做Array.Sort排序正確。

+0

它看起來像你缺少一個。 :Sort-Object {$ _。Name -as [version]},而不是Sort-OBject {$ _Name -as [Version]} – 2011-12-21 01:55:52

+0

我注意到,發佈這個之後,請原諒我的胖手指。出於興趣,爲什麼沒有拋出錯誤?它只是試圖找到一個變量$ _Name而沒有找到它,並嘗試將null傳遞給構造函數? – jonnii 2011-12-21 14:31:59

+1

PowerShell中的屬性訪問從不拋出錯誤(它們寫入$ error),而是返回空值。這樣當你顯示一個對象的某些屬性不起作用時,你不會交錯錯誤和輸出。您可以通過打開嚴格模式來切換PowerShell如何處理此操作:Set-StrictMode -Version Latest。 – 2011-12-21 20:13:27

回答

1

自然排序是您想要的順序。的1,10,11,2,3 1,2,3..10,11..instead ..

1..11 | %{$_.tostring()} | sort 

使得它在「ASCIIbetical」命令,這不是我們期望它的自然秩序在

根據你用的版本做什麼,我會說,你可以這樣做,但它可能是一個有點過板:

gci directory | %{new-object psobject -p @{version=[version]($_.name);dir=$_ }} | 
sort version | select -expand dir -first 5 | rm -r -whatif 

gci directory | select @{e={[version] $_.name};l="version"}, @{e={$_};l="dir"} | 
sort version | select -expand dir -first 5 | rm -r -whatif 
+0

我很想嘗試把中間結果放到一個對象中,也許是一個「Tuple」或字典......我會試試這個,讓你知道我是怎麼開始的。 – jonnii 2011-12-19 22:19:44

7

實際上,您可以對錶達式進行排序,這會保留原始對象。

Get-ChildItem $path | 
    Sort-Object { $_.Name -as [Version] } | 
    Select-Object -Last 1 | 
    Remove-Item 

會做的伎倆。

希望這會有幫助,

+0

+1使用'-as'運算符。優雅:-) – 2011-12-19 22:55:24

+1

這是優雅的,不是'-as'運算符,而是表達式。沒有意識到你可以做到這一點。 – manojlds 2011-12-19 23:33:22

+2

對於Select-Object&Group-Object也是如此。當您在產品團隊中完成整個船週期的工作時,您會學到一件事或者一千件事,然後找到專門用於該語言的公司:-)這絕對是我最喜歡的核心PowerShell cmdlet的角落之一。 這個舊視頻涵蓋了一些我最喜歡的對象集: http://channel9.msdn.com/Blogs/philpenn/PowerShell--Object-Family-of-CmdLets-and-the-Object-Pipeline – 2011-12-20 04:04:54