2

I have a folder with multiple files and need to rename them to a string inside of the folder. The string is the date of interaction.

Currently the files are named as

AUDIT-1.log
AUDIT-2.log
AUDIT-3.log

ect..

I need to have them as

AUDIT-11-08-22-1.log
AUDIT-11-07-22-2.log
AUDIT-11-08-22-3.log

The issue I am having with the current iteration of the code, the dates of all files are collected and it attempts to rename the file with all dates

EXAMPLE:

NewName: 11-08-22 11-07-22 11-06-22 11-09-22 11-08-22 11-07-22 11-06-22 11-09-22-1.LOG
OldName: C:\TestTemp\AUDIT-2.LOG

There is only one date in each file.

The following is my current code:

$dir ="C:\TestTemp"
$files = Get-ChildItem -Path "$dir\*.log"
$RegexDate = '\d\d\/\d\d\/\d\d'

Measure-Command{

$file_map = @()
foreach ($file in $files) {
    $DateName= Get-Content $files | 
Select-String $RegexDate |
foreach-object { $_.Matches.Value } |
Select-Object
    $NewDateName= $DateName.replace('/','-')
$b = 1 
    $file_map += @{
        OldName = $file.Fullname
        NewName = "$NewDateName-$b.LOG" -f $(Get-Content $file.Fullname | Select-Object $NewDateName.Fullname)
    }
}

$file_map | ForEach-Object { Rename-Item -Path $_.OldName -NewName $_.NewName }

}
3
  • 3
    Get-Content $files ? it should be $file. Also Select-String can read files ;) no need to Get-Content Commented Jan 10, 2023 at 14:32
  • 1
    hah, thank you. I have been staring at this for far longer than I care to admit. Much appreciated! Commented Jan 10, 2023 at 14:58
  • 1
    How about: Select-String -Path "$dir\*.log" -Pattern '(\d+\/){2}\d+' | Rename-Item -NewName { $1,$2 = $_.FileName -split '-'; "$1-" + $_.Matches.Value.Replace('/','-') + "-$2" } -WhatIf Commented Jan 10, 2023 at 15:05

2 Answers 2

2

This will rename the files using their last write time. If the files were already in that format, they will not be renamed. There is a hashtable to track the increment of the suffix for the date of the file. This way the files can be organized by date.

$dir = "C:\TestTemp"
$files = Get-ChildItem -Path "$dir\*.log"


#Hashtable to track the suffix for the files
[hashtable]$dateTracking = @{}

#Using padding to format the suffix with two digits, in case there more then 9 files
#incrase it if you have more then 99 files per day increase padding
$suffixPadding = '{0:d2}'

foreach ($file in $files) {
    #Don't rename files that were already renamed
    if ($file.Name -notmatch "AUDIT-\d{2}-\d{2}-\d{2}-\d{2}\.log") {
        $date = $file.LastWriteTime.ToString("MM-yy-dd")
        #If the date is not entered in the hashtable add it with suffix 01
        if (-not $dateTracking.ContainsKey($date)) {        
            $dateTracking.Add($date, $suffixPadding -f 1)
        }
        #Else increment suffix
        else {
            $dateTracking[$date] = $suffixPadding -f ([int]$dateTracking[$date] + 1)
        }
        #Here we use the date in the name of the file and getting the suffix from the hashtable
        Write-Host "Renaming $($file.Name) to AUDIT-$date-$($dateTracking[$date]).log"
        Rename-Item -Path $file -NewName "AUDIT-$date-$($dateTracking[$date]).log"
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

As pointed out in the comments by Santiago Squarzon, the immediate fix is to swap $files, for $file. For code brevity, here's a single pipeline solution you can implement to attain the same results:

Select-String -Path "$dir\*.log" -Pattern '(\d+\/){2}\d+' | 
    Rename-Item -NewName { 
        $_.FileName -replace '-', "-$($_.Matches.Value.Replace('/','-'))-" 
    } -WhatIf

Again, as mentioned in the comments, the use of Select-String allows the reading of file(s) presenting the opportunity to pipe directly into Rename-Item via parameter binding through its Path property. So, using a scriptblock for the new name replacement we're essentially inserting the value found from it's pattern matched into the file name where - would have been.


The -WhatIf safety/common parameter can be removed when you've dictated those are the results you are after.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.