Я хочу получить последний файл в каталоге и использовать его имя файла без (Count), чтобы проверить, имеют ли он те же имена, что и остальные файлы.
Если имя файла совпадает, переименуйте его в $(Get-Date -Format yyyymmddhhmmss)_$ScreenTitle и переместите в выходную папку.
Если нет, ничего не делайте.
Обновлено:
Это имена файлов по умолчанию со снимка экрана игровой панели Xbox (Win+Alt+PrtSc):
Приведенный ниже код работает правильно (спасибо @Theo!) но я понял, что время имени файла меняется, поэтому оно не соответствует регулярному выражению.
$ParentFolder = "$env:USERPROFILE\Videos\Captures"
#Set-Location $ParentFolder
# Create an Output Folder wether It's Existing or Not
New-Item $ParentFolder\Output -Force -ItemType Directory | Out-Null
$OutputFolder = ".\Output"
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
$newestFile
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'
$dateToday = Get-Date -Format "yyyymmddhhmmss"
# create the new filename
$NewFileName = '{0}_[{1}]{2}' -f $dateToday, $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)
}
}
Немного неясно, хотите ли вы использовать дату, которая является частью имени файла в перемещенном файле, или текущую дату. Вы также не говорите, в каком формате должна быть эта дата при использовании ее в новом имени файла.
См. комментарии в коде ниже для альтернатив на дату
$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
}
}
Согласно вашему комментарию, ниже обновленного ответа:
$ParentFolder = 'Z:\WhereTheFilesAre'
$OutputFolder = 'X:\TheSestinationFolder'
Get-ChildItem -Path $ParentFolder -Filter '*.png' -File |
Where-Object { $_.BaseName -match '^(.+)\s+(\d{2}_\d{2}_\d{4}\s+\d{2}_\d{2}_\d{2}\s+[ap]m).*$' } | # filter more specific
Group-Object { $_.BaseName -replace '\s+\d{2}_\d{2}_\d{4}\s+\d{2}_\d{2}_\d{2}\s+[ap]m.*$' } | # group on screen title
Where-Object { $_.Count -gt 1 } | ForEach-Object {
# get the latest file
$newestFile = $_.Group | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$screentitle = $_.Name
# scenario 1: Take the date from the file name
$dateFromFileName = $newestFile.BaseName -replace '^.+\s+(\d{2}_\d{2}_\d{4}\s+\d{2}_\d{2}_\d{2}\s+[ap]m).*$', '$1'
# parse the date from the file name
$date = [datetime]::ParseExact($dateFromFileName, 'MM_dd_yyyy h_mm_ss tt', [cultureinfo]::InvariantCulture)
# create the new filename
$NewFileName = '{0:yyyyMMddHHmmss}_[{1}]{2}' -f $date, $screenTitle, $newestFile.Extension
# scenario 2: Use the LastWriteTime property from the newest file (much easier)
# $NewFileName = '{0:yyyyMMddHHmmss}_[{1}]{2}' -f $newestFile.LastWriteTime, $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
}
@jeriru Трудно сказать .. Остались ли какие-либо файлы в родительской папке, и если да, то имеют ли они тот же формат, что и примеры, которые вы привели? Можете ли вы привести новые примеры имен файлов, которые больше не совпадают?
Да, мы с @Theo уже видели, что регулярное выражение ничему не соответствует, потому что изменяется формат времени из имени файла. Как мне его изменить? Должен ли я добавить еще одно условие If? Пожалуйста, проверьте отредактированный пост на наличие имен файлов, спасибо!
Привет! @Theo, еще раз спасибо за это :) Я запустил ваш код, когда он работает именно так, как мне нравится, но после перезапуска ISE код больше не переходит к регулярному выражению -match. Что может пойти не так?