0

Currently im using

dir | Rename-Item -NewName {$_.name -replace "",""}

to rename files in a directory. The file names vary and need to be unified.

Examples for file names:

  1. 20211112_CLAM_30001_Important information on xyz_DK
  2. CLAM_DK_20201002_30001_Protocol for PA01 - email
  3. DK_30001_Update on customer increase_signed_20220102

Unified format:

CLAM_30001_Arbitrary text_yyyymmdd

There is a date as an 8 digit no. at an arbitrary position in the file name. The date needs to be the very end of the file name. How can I move it to the end? (Perhaps REGEX?)

5
  • Id usually use a regular expression with 3 capture groups; everything before the date, the date, and everything after the date. then I'd use an replace expression like $0$2$1 to combine what is before and after the date, and drop the date at the end. Jan 21, 2022 at 18:09
  • 2
    please add a few sample file names to your Question for folks to work with. concrete is easier to tinker with than abstract. [grin]
    – Lee_Dailey
    Jan 21, 2022 at 19:16
  • I added some sample file names. Thanks for your help! :)
    – schwadinho
    Jan 22, 2022 at 20:08
  • if you use $_.name -match '(19|20\d{2})(\d{2})(\d{2})' or another regex of your choice - you will have the complete date in $Matches[0] and you can put it wherever you want
    – SimonS
    Jan 22, 2022 at 20:26
  • @schwadinho - thank you for the added info. [grin] ///// now ... do you really want to combine those 3 input file names into one file name? if not ... please show what you want each to end up with. exactly what you want each of those demo file names to become.
    – Lee_Dailey
    Jan 23, 2022 at 1:16

2 Answers 2

0

Try the following:

gci | Where { $_.Name -Match '\d{8}'} | ForEach {
        if ($_.Name -Match '^(\d{8})_(.+)$') { 
            Rename-Item $_ ( $_.Name -Replace  '^(\d{8})_(.+)$','$2_$1' ) }
        elseif ($_.Name -Match '^(.+_)(\d{8})_(.+)$') { 
            Rename-Item $_ ( $_.Name -Replace '^(.+_)(\d{8})_(.+)$', '$1$3_$2' ) }
    }

The code checks where the 8 digits are found in the filename (beginning or other) and rename the files accordingly. No need to check if the 8 digits are at the end.

0

You can do this without ForEach-Object using a scriptblock for parameter -NewName in which you simply move the captured 8 digits result from the Where-Object clause towards the end of the file's BaseName.
Then trim off any leading or trailing underscores and make sure there will be no doubled-up underscores in the new name. Finally append the file's extension (if any).

If a file already had the desired name format, it will not be renamed (a no-op)

Get-ChildItem -Path 'X:\ThePath' -File | Where-Object { $_.BaseName -match '(\d{8})' } | 
Rename-Item -NewName { (('{0}_{1}' -f ($_.BaseName -replace $matches[1] ), $matches[1]).Trim("_") -replace '_+', '_') + $_.Extension }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .