0
Get-ChildItem -Filter *_* | Foreach-Object -Process {
     $NewName = [Regex]::Match($_.Name,"^[^ _]*").Value +'.jpg'
     $_ | Rename-Item -NewName $NewName
 }

I have been using this code to rename files

For example, 569_SOM_TEST.jpg to 569 but if there is 569_TOB_TEST.jpg, It gives an error Rename-Item : Cannot create a file when that file already exists.

I want it to make it 569-1.

How can I accomplish this?

0

1 Answer 1

1

To prevent renaming clashes, you can put the below helper function at the top of your script:

function Rename-FileUnique {
    # Renames a file. If a file with that name already exists,
    # the function will create a unique filename by appending '(x)' after the
    # name, but before the extension. The 'x' is a numeric value.
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
        [string]$Path,

        [Parameter(Mandatory = $true, Position = 1)]
        [string]$NewName,

        [switch]$PassThru
    )
    # Throw a bit nicer error than with [ValidateScript({Test-Path -Path $_ -PathType Leaf})]
    if (!(Test-Path -Path $Path -PathType Leaf)){
       Throw [System.IO.FileNotFoundException] "Rename-FileUnique: The file '$Path' could not be found."
    }

    # split the new filename into a basename and an extension variable
    $baseName  = [System.IO.Path]::GetFileNameWithoutExtension($NewName)
    $extension = [System.IO.Path]::GetExtension($NewName)    # this includes the dot
    $folder    = Split-Path -Path $Path -Parent

    # get an array of all filenames (name only) of the files with a similar name already present in the folder
    $allFiles = @(Get-ChildItem $folder -Filter "$baseName*$extension" -File | Select-Object -ExpandProperty Name)
    # for PowerShell version < 3.0 use this
    # $allFiles = @(Get-ChildItem $folder -Filter "$baseName*$extension" | Where-Object { !($_.PSIsContainer) } | Select-Object -ExpandProperty Name)

    # construct the new filename / strip the path from the file name
    $NewName = $baseName + $extension   # or use $NewName = Split-Path $NewName -Leaf

    if ($allFiles.Count) {
        $count = 1
        while ($allFiles -contains $NewName) {
            $NewName = "{0}-{1}{2}" -f $baseName, $count++, $extension
        }
    }
    Write-Verbose "Renaming '$Path' to '$NewName'"
    Rename-Item -Path $Path -NewName $NewName -Force -PassThru:$PassThru
}

and use it like:

Get-ChildItem -Filter '*_*.jpg' | Foreach-Object {
    # create the proposed new filename
    $newName = '{0}.jpg' -f ($_.Name -split '_')[0]
    $_ | Rename-FileUnique -NewName $newName
 }

This will ensure that any proposed new filename gets a not already used index number attached to its basename.

Sign up to request clarification or add additional context in comments.

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.