Home > database >  Get the latest file and compare its filename with the rest of the files
Get the latest file and compare its filename with the rest of the files

Time:11-23

I want to get the latest file in a directory and use its filename without the (Count) to check if it has same names with the rest of the files.

If filename matches, Rename it as $(Get-Date -Format yyyymmddhhmmss)_$ScreenTitle and move it to Output folder.

If not, Do nothing.

These are the sample filenames:

filenames

and My Terminal Output should look like this:

The Root Name in: Captures 11_21_2022 10_59_21 AM (2).png is Captures 11_21_2022 10_59_21 AM

Captures 11_21_2022 10_59_21 AM has same filename with Captures 11_21_2022 10_59_21 AM (1)

Captures 11_21_2022 10_59_21 AM has same filename with Captures 11_21_2022 10_59_21 AM

With my current work, I have 3 questions:

  1. How can I properly get the filename without the () in $RootName?

  2. How can I -Exclude the $LatestFile but also select .png files only?

  3. How can I extract the Date&Time in a filename in $ScreenTitle or get the word "Captures" only in filename?

# Get the Latest File in the Current Directory
$LatestFile = GCI -Attributes !Directory *.png | Sort-Object -Descending -Property LastWriteTime | Select -First 1
$LatestFilename = $LatestFile.Name

# Not sure if this is the best way to exclude the () in filenames
$RootName = $LatestFilename.split('(')[0]

# This is where I get confuse, Select All the .png Files in the directory Except the latest file
$AllFiles = GCI -LiteralPath $ParentFolder  -Filter '*.png' -File -Exclude $LatestFile
$AllFiles
ForEach($File in $AllFiles){
$Filename = $File.Name

If($RootName -Like $Filename){

    Write-Host "The Root Name in:" $Filename "is =" $RootName
    Write-Host $RootName "has same filename with" $Filename
    
    # Not sure If I can extract and remove the Date&Time using this
    $NameCount   = $FileName.Length
    $ScreenTitle = $FileName.Substring(0, $NameCount -21)

    $NewFileName = '{0}_[{1}]{2}' -f  $Date, $ScreenTitle, ".png"

    # Move the latest file with a new name to the destination
    $LatestFile | Move-Item -Destination (Join-Path -Path $OutputFolder -ChildPath $NewFileName)

} }

CodePudding user response:

It is a bit unclear if you want to use the date that is part of the file name in the moved file or the curent date. You also do not say in what format that date should be when using it in the new file name.

See the comments in the code below for alternatives on the date

$ParentFolder = 'Z:\WhereTheFilesAre'
$OutputFolder = 'X:\TheSestinationFolder'

Get-ChildItem -Path $ParentFolder -Filter '*.png' -File | Group-Object {$_.BaseName.Split("(")[0].TrimEnd()} | 
Where-Object { $_.Count -gt 1 } | ForEach-Object {
    # get the latest file
    $newestFile = $_.Group | Sort-Object LastWriteTime -Descending | Select-Object -First 1
    if ($newestFile.BaseName -match '^(. )\s (\d{2}_\d{2}_\d{4}\s \d{2}_\d{2}_\d{2}\s [ap]m).*$') {
        $screentitle      = $matches[1]
        $dateFromFileName = $matches[2]  # the date from the filename unaltered like '11_21_2022 10_59_21 AM'

        # if you want the date from the file name formatted like 'yyyy_MM_dd HH-mm-ss'
        # $date = [datetime]::ParseExact($dateFromFileName, 'MM_dd_yyyy h_mm_ss tt', [cultureinfo]::InvariantCulture)
        # $dateFromFileName = '{0:yyyy_MM_dd HH-mm-ss}' -f $date

        # create the new filename
        $NewFileName = '{0}_[{1}]{2}' -f $dateFromFileName, $screenTitle, $newestFile.Extension

        # Move the file with a new name to the destination
        Write-Host "Moving file '$($newestFile.Name)' as '$NewFileName'"
        $newestFile | Move-Item -Destination (Join-Path -Path $OutputFolder -ChildPath $NewFileName)

        # what do you want to do with the rest of the files that were older? Delete them?
        # $_.Group | Sort-Object LastWriteTime -Descending | Select-Object -Skip 1 | Remove-Item
    }
}
  • Related