I'm attempting to rename files using Powershell. Im really not sure which approach is best to accomplish this. The files are generated and named by the POS system in the format shown below. I would like to make them easily readable and sortable in a folder for later processing by a data entry clerk. Here's what I have so far. I thought the best approach would be regex but now im not sure. Any help would be greatly appreciated.
Examples: (Date Time Report Name)
StoreClose20230122220648 ---> 2023-01-22 220648 Store Close
TillSummeryClose20230122220648 ----> 2023-01-22 220648 Till Summery Close
Attempted to use regex with no sucesss.
for ($i = 0; $i -lt $files.Count; $i ) {
$BaseName = $files[$i].BaseName
$FileExt = $files[$i].Extension
$NewName = ($BaseName -csplit '([0-9] )' -ne '' -join '-').Trim("")
Write-Output (-join($NewName, $FileExt))
}
$SRC = "$env:USERPROFILE\Desktop\From Here"
$DST = "$env:USERPROFILE\Desktop\To Here"
$EXT = "*.pdf", "*.log", "*.txt"
$SRC_EXST = Test-Path -Path $SRC -ErrorAction SilentlyContinue
$DST_EXST = Test-Path -Path $DST -ErrorAction SilentlyContinue
$CWD = $PSScriptRoot
if (!$SRC_EXST) {
Write-Output "$(Get-Date) Invalid source(SRC) path [$SRC]." | Out-File -FilePath "$CWD\log.txt" -Encoding utf8 -Append
exit
}
if (!$DST_EXST) {
Write-Output "$(Get-Date) Invalid destination(DST) path [$DST]." | Out-File -FilePath "$CWD\log.txt" -Encoding utf8 -Append
exit
}
$files = Get-ChildItem -Path "$SRC\*" -Include $EXT
for ($i = 0; $i -lt $files.Count; $i ) {
$BaseName = $files[$i].BaseName
$FileExt = $files[$i].Extension
$NewName = ($BaseName -csplit '([0-9] )' -ne '' -join '-').Trim("")
Write-Output (-join($NewName, $FileExt))
}
CodePudding user response:
To split these names into a name part including spaces between the capitalized words and a date part, you need to do more work.
Helas, in your question it is not clear if you just want to rename these files or copy them to a new location under a new name. The code below shows how to do it:
$SRC = "$env:USERPROFILE\Desktop\From Here"
$DST = "$env:USERPROFILE\Desktop\To Here"
$EXT = "*.pdf", "*.log", "*.txt"
$LOG = Join-Path -Path $PSScriptRoot -ChildPath 'log.txt'
if (-not (Test-Path -Path $SRC -PathType Container)) {
"$(Get-Date) Invalid source(SRC) path [$SRC]." | Add-Content -Path $LOG -Encoding utf8
exit
}
if (-not (Test-Path -Path $DST -PathType Container)) {
"$(Get-Date) Invalid destination(DST) path [$DST]." | Add-Content -Path $LOG -Encoding utf8
exit
}
# loop thhrough the files
Get-ChildItem -Path $SRC -File -Recurse -Include $EXT |
Where-Object { $_.BaseName -match '\d{14}$' } | # should end in 14 digits
ForEach-Object {
$name = $_.BaseName -replace '\d{14}$'
$time = $_.BaseName -replace "^$name"
$date = [datetime]::ParseExact($time, 'yyyyMMddHHmmss', $null)
# insert spaces in front of each Capital letter in the name (make sure only one single space)
$name = ($name -creplace '([A-Z])', ' $1').Trim() -replace '\s ', ' '
# recombine these parts to create the new file name
$newName = '{0:yyyy-MM-dd HHmmss} {1}{2}' -f $date, $name, $_.Extension
# if you want to RENAME the file in the source directory:
$_ | Rename-Item -NewName $newName -WhatIf
# if you want to COPY the file with a new name to the destination path leaving the source file as-is:
# $_ | Copy-Item -Destination (Join-Path -Path $DST -ChildPath $newName) -WhatIf
}