powershellrename-item-cmdlet

File renaming with powershell


Script is working almost how it is intended, still struggling with renaming duplicate files. I cannot figure out how to get it to name the files like

filename(1).ext

filename(2).ext

the closest I have gotten was

filename(1).ext

filename(1)(2).ext

 #region actual script
 $srcRoot = "C:\srcLocation"
 $dstRoot = "C:\dstLocation"

 $fileList = Get-ChildItem -Path $srcRoot -File -Force -Recurse

    foreach ($file in $fileList) {


    $fileName = $file.Name.ToUpper()
    $fileExt = $file.Extension.ToUpper()
     $dstFileName = $null

     switch -Regex ($fileName)
    {
   '[A-Z]{4}-[0-9]{3}' { $dstFileName = $fileName }
   '[A-Z]{4} [0-9]{3}' { $dstFileName = $fileName -replace '([A-Z]{4})\s([0-
    9]{3})','$1-$2' }
   '[A-Z]{4}[0-9]{3}' { $dstFileName = $fileName -replace '([A-Z]{4})([0-9]
    {3})','$1-$2'}
   Default { Write-Warning -Message "$fileName is not an expected filename" 
   }
   }

   if ($dstFileName) {
   $dstDir = $dstFileName.Split('.')[0].Substring(0,8)
   $dstPath = Join-Path -Path $dstRoot -ChildPath $dstDir

   if (-not (Test-Path -Path $dstPath)) {
       New-Item -Path $dstPath -ItemType Directory
   }
   $i = 1
   if (test-path $dstPath\$dstFileName){
           $dstFileName = $dstFileName.Split('.')[0] + "($i)" + $fileExt

   While (test-path $dstPath\$dstFileName){
        $i +=1
        $dstFileName = $dstFileName -replace 

   }
   }


   Write-Verbose "Moving $($file.FullName)"
   Move-Item -Path $($file.FullName) -Destination $dstPath\$dstFileName -
   ErrorAction Continue
   }
   }
   #endregion

Solution

  • You can simply use the Replace method of string objects in PowerShell. To verify your input, you can use a RegEx. Move-Item will throw an error, if the file already exists in the destination anyways. The complete script would look like this.

    #region setup
    New-Item -Path C:\srcpath,C:\dstpath -ItemType Directory
    Set-Location C:\srcpath
    New-Item 'ABCD123.txt','ABCD 123.txt','AbCD-123.txt','AAAA111.txt','BBBB 222.jpg','BBBB-222.txt' -ItemType File
    #endregion
    
    #region actual script
    $srcRoot = "C:\srcpath"
    $dstRoot = "C:\dstpath"
    
    $fileList = Get-ChildItem -Path $srcRoot -File -Force -Recurse
    
    foreach ($file in $fileList) {
    
        $fileName = $file.Name.ToUpper()
        $dstFileName = $null
    
        switch -Regex ($fileName)
        {
            '[A-Z]{4}-[0-9]{3}' { $dstFileName = $fileName }
            '[A-Z]{4} [0-9]{3}' { $dstFileName = $fileName -replace '([A-Z]{4})\s([0-9]{3})','$1-$2' }
            '[A-Z]{4}[0-9]{3}' { $dstFileName = $fileName -replace '([A-Z]{4})([0-9]{3})','$1-$2'}
            Default { Write-Warning -Message "$fileName is not an expected filename" }
        }
    
        if ($dstFileName) {
            $dstDir = $dstFileName.Split('.')[0]
            $dstPath = Join-Path -Path $dstRoot -ChildPath $dstDir
    
            if (-not (Test-Path -Path $dstPath)) {
                New-Item -Path $dstPath -ItemType Directory
            }
    
            Write-Verbose "Moving $($file.FullName)"
            Move-Item -Path $($file.FullName) -Destination $dstPath\$dstFileName -ErrorAction Continue
        }
    }
    #endregion
    
    #region result
    Write-Host '----- Result -----' -BackgroundColor DarkYellow
    Get-ChildItem C:\dstpath -Recurse | Select-Object -ExpandProperty FullName
    #endregion