1

I have been struggling with the following on powershell:

I have files with the first 3 characters referencing an ID and the rest of the filename contains a timestamp.

ABC.2019-10-23 SIZE: 5KB

ABC.2019-10-22 SIZE 7KB

DEF.2019-10-23 SIZE 4KB

DEF.2019-10-22 SIZE 11KB

Now the files are of different file sizes. What I would like to do is rename the largest files that include a distinct ID.

All the files are in the same folder and can be looped through without recursion.

After completing the task it should have renamed the files:

ABC.2019-10-22.old

DEF.2019-10-22.old

Because the first one is the largest file that contains the 3 character substring ABC

And the second file is the largest file that contains the substring DEF

This should be done to all the biggest files containing a distinct 3 character ID

Any help would be much appreciated!

  • Please _edit the question_ and describe with more details about the renaming: what exactly should be old and new names? Perhaps picking short filenames for sample data would help, as trying to see what the GUIDs are about is confusing. – vonPryz Oct 23 '19 at 12:57
  • Hello I edited the question as you asked @vonPryz. – Simo Korpikoski Oct 23 '19 at 13:04
  • 1
    use `Group-Object` with a calculated grouping target [the 1st 3 chars], sort each group by `.Length`, then rename the largest. – Lee_Dailey Oct 23 '19 at 13:11

1 Answers1

1

Lee_Daily has provided the outline of a solution in a comment:

use Group-Object with a calculated grouping target [the first 3 chars], sort each group by .Length, then rename the largest.

To put this into concrete terms:

Get-ChildItem -File | 
  Group-Object { $_.Name -replace '\..+' } | 
    ForEach-Object { 
      $_.Group | Sort-Object Length -Descending | Select-Object -First 1 |
        Rename-Item -NewName { $_.Name + '.old' } -WhatIf
    }

-WhatIf previews the operation. Remove it once you're sure it will do what you want.

  • Get-ChildItem -File enumerates all files in the current directory (adapt as needed).

  • The Group-Object call groups the files by their names' first .-separated token (e.g., ABC, DEF)

    • $_.Name -replace '\..+' uses a regular expression to effectively remove everything starting with the first literal . char. from the input string (file name) - see this answer for more information about the -replace operator; e.g.,
      'ABC.More.Tokens' -replace '\..+' yields 'ABC'
  • The ForEach-Object call processes each resulting group (.Group):

    • The Sort-Object call sorts descending by file size (.Length).
    • The Select-Object -First 1 then selects only the first - and therefore largest - file.
      • Note: In PowerShell Core you could combine the Sort-Object and Select-Object calls to Sort-Object -Top 1
    • Finally, the Rename-Item renames the file by appending .old to the existing name.
mklement0
  • 382,024
  • 64
  • 607
  • 775