Group items based on x number characters of basename

3.3k Views Asked by At

I got help to setup a clever script that groups items in a folder based on basename and LastWriteTime it lets me delete everything except given number of files (i.e 5 versions). Now I'd like to limit basename grouping to 8 characters.

gci C:\test\ |
where{-not $_.PsIsContainer} |
$file = basename
Group-Object $file.substring(8) |
foreach {
  $_.Group |
  sort LastWriteTime -Descending |
  Select -Skip 5 |
   foreach { Remove-Item $_.fullname -Force -WhatIf }
  }

As I'm really new to powershell I'm not sure if above is correct approach.

1

There are 1 best solutions below

4
On BEST ANSWER

If you want to group by the first 8 characters, you need Substring(0, 8). Substring(8) will produce the substring from the 9th character to the end of the string. Also, if you want to group by properties of the current object, you define them in a scriptblock.

Change this:

gci C:\test\ |
where{-not $_.PsIsContainer} |
$file = basename
Group-Object $file.substring(8) | ...

into this:

Get-ChildItem 'C:\test' |
  Where-Object {-not $_.PSIsContainer} |
  Group-Object { $_.Basename.Substring(0,8) } | ...

Note that Substring(0,8) will throw an error if the basename is shorter than 8 characters. You can avoid that for instance by defining the length as the minimum of 8 and string length:

$_.Basename.Substring(0, [Math]::Min(8, $_.Basename.Length))