简体   繁体   中英

Delete oldest versions of a directory in PowerShell

I have a list of directories which are formatted like version numbers and would like to find the N oldest directories and delete them. For example:

/1.2.3.4
/1.2.3.5
/1.2.3.6

I've tried a few things, but I can't quite seem to get where I need to go.

My first try was this:

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

However I'm not sure this is going to work in all circumstances, because this will (I presume) do a natural sort. Is that always going to return the correct results?

My next thought was that I could use System.Version to do my sorting. So I ended up with this:

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

The problem is that I'm not sure how to tie the directory result to the sorting... What's the best way to do this?

gci \\\\directory produces

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] } gci \\\\directory | Sort-Object { $_Name -as [Version] } produces

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

Does it matter that this is a network share? I'm confused as to why this isn't working... I did a quick sanity check and doing Array.Sort on versions I've created in a unit test are sorted correctly.

You can actually sort on an expression, which will keep your original objects.

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

Will do the trick.

Hope this helps,

Natural sort is the order that you want. 1,2,3..10,11..instead of 1,10,11,2,3..

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

Gives it in "ASCIIbetical" order, which is not the natural order we expect it to be in.

Based on what you were doing with version, I would say you can do like this, though it might be a bit over board:

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

or

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM