Keep the newest file in each month and delete the rest RRS feed

  • Question

  • Hi,

    I've got a hash table that has a file name and a date.  In one month there are multiple files created and I want to keep the newest and delete the rest.

    Does anyone have any logic or at least a pointer how I could do this?  Here is what I have:

    file1 2018-04-15
    file2 2018-03-04
    file3 2018-04-15
    file4 2018-03-11
    file5 2018-02-04
    file6 2018-04-15
    file7 2018-04-08
    file8 2018-03-18
    file9 2018-04-08
    file10 2018-04-22

    For each unique month in the list, keep the eldest and delete the rest!

    Alter De Ruine

    Monday, June 11, 2018 3:26 PM

All replies

  • Where is the hash table?  What have you tried?  Post your script.


    Monday, June 11, 2018 3:53 PM
  • The code below is based strictly on the format listed above for your hash table.  In the code, the hash table that would contain the file/date information is called $fileHashTable.  To note, if your dates do not include a time stamp you will not be able to accurately tell the difference between two files with the same date.  Hope this helps.

    $monthArray = @();
    $dateValues = $fileHashTable.Values;
    Foreach($date in $dateValues){
    	$date -match "^(\d{4}\-\d{2})\-\d{2}$" | Out-Null;
    	$month = $matches[1];
    	$monthArray += $month;
    $uniqueMonthArray = $monthArray | Sort-Object -Unique;
    $valueOfFilesToRemove = @();
    $currentEntryArray = @();
    Foreach($monthEntry in $uniqueMonthArray){
    	$currentEntryArray = $dateValues | where {$_ -match $monthEntry};
    	$newestDate = ($currentEntryArray | Get-Date | Sort-Object -Descending)[0];
    	$valueOfFilesToRemove += $currentEntryArray | where {$_ -notmatch ($newestDate.GetDateTimeFormats())[5]};
    $keys = $fileHashTable.Keys;
    Foreach($file in $keys){
    	$fileEntry = $fileHashTable[$file];
    	if($valueOfFilesToRemove -contains $fileEntry){
    		Write-Host "File to remove - $file";

    Tuesday, June 12, 2018 3:49 AM
  • I have bot tested it, but this should do the trick:
    $groups = $Files.GetEnumerator() | group {$_.Value -replace "-\d{2}$"}
    foreach($g in $groups){
        $g.Group | sort Value -Descending | select -Skip 1 | foreach{Remove-Item $_.Key}
    The data is grouped by year and month (which is the datekey without the last two digits and the minus before). Then, inside of each group files are sorted by date, the first one is skipped and the following ones are deleted.
    Tuesday, June 12, 2018 9:26 AM