1

I'm trying to write a script to remove characters from file names in a certain folder using PowerShell. It prompts the user to enter how many characters they want removed from the front, back, and a certain string they want removed.

# Prompt User how many characters in the front they want removed
$FrontRemove = Read-Host 'Enter how many characters you want removed from the front'

# Prompt user how many characters in the back they want removed
$BackRemove = Read-Host 'Enter how many characters you want removed from the back'

# Prompt user for string to be removed
$MiddleRemove = Read-Host 'Enter a string you want removed from the file name'

dir | Rename-Item -NewName{$_.name.substring(0,$_.BaseName.length-$BackRemove)}
dir | Rename-Item -NewName{$_.name.substring($FrontRemove)}
dir | Rename-Item -NewName{$_.name -replace "$MiddleRemove", ""}

The current issue I'm having is that it's removing the extensions of these files and it's also renaming the script itself. How would I go about keeping file extensions and excluding .ps1?

1
  • dir is an alias for Get-ChildItem. Check out the help (linked) for details of how to include/exclude items from the enumeration. Commented Oct 5, 2018 at 15:09

1 Answer 1

2

There are a few things I would change in your code. For one thing, you call dir (Get-ChildItem) for every change of the file names when you could do that in one call.

Also, it lacks any form of checking to see if what the user has entered can actually be done for each file the Get-ChildItem returns.

The Get-ChildItem without a path specified will search items in the current location. If that is not what you want, maybe it is safer to set the path like in the code below.

$folder = '<ENTER THE PATH TO THE FOLDER WHERE THE FILES TO RENAME ARE HERE>'

# Prompt User how many characters in the front they want removed --> number
[int]$FrontRemove = Read-Host 'Enter how many characters you want removed from the front'

# Prompt user how many characters in the back they want removed --> number
[int]$BackRemove = Read-Host 'Enter how many characters you want removed from the back'

# Prompt user for string to be removed --> string
[string]$MiddleRemove = Read-Host 'Enter a string you want removed from the file name'

# Since we are using the -replace function, which is using Regular Expression replacement,
# we need to make sure all 'special' characters in the string are escaped.
if (![string]::IsNullOrEmpty($MiddleRemove)) {
    $MiddleRemove = [Regex]::Escape($MiddleRemove)
}

Get-ChildItem -Path $folder -File | Where-Object {$_.Name -notlike '*.ps1'} |
    ForEach-Object {
        $directory = $_.DirectoryName     # or [System.IO.Path]::GetDirectoryName($_.FullName)  or use Split-Path $_.FullName -Parent
        $filename  = $_.BaseName          # or [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
        $extension = $_.Extension         # or [System.IO.Path]::GetExtension($_.Name)

        # test user input and remove/replace only if possible
        if ($FrontRemove -gt 0 -and $FrontRemove -lt $filename.Length) {
            $filename = $filename.Substring($FrontRemove)
        }
        if ($BackRemove -gt 0 -and $BackRemove -lt $filename.Length) {
            $filename = $filename.Substring(0, $filename.Length - $BackRemove)
        }
        if (![string]::IsNullOrEmpty($MiddleRemove)) {
            $filename = $filename -replace $MiddleRemove, ''
        }

        # now see if we still have a name left and if indeed the filename has changed
        if (![string]::IsNullOrEmpty($filename) -and $filename -ne $_.BaseName) {
            # re-append the extension of the file
            if (![string]::IsNullOrEmpty($extension)) { $filename += $extension }
            # join it with the directory to become a complete path and filename
            $newname = Join-Path -Path $directory -ChildPath $filename
            Rename-Item -LiteralPath $_.FullName -NewName $newname -Force
        }
        else {
            Write-Warning "The options you entered would remove the entire filename. Action skipped on '$($_.FullName)'"
        }
    }
Sign up to request clarification or add additional context in comments.

6 Comments

I'm not too sure why, but when I tried running that, it closes out. There's some error stuff at the top but the window closes too fast for me to read. I omitted the folder part for the file path to test out if it would skip the .ps1. Reading through your code, it seems to me like it would work just fine so maybe it's something on my end?
It should at least ask for the user input before failing no? Sorry I'm very new to powershell. I've only ever used python to code simple games.
Try running it from the Powershell ISE. From the editor it is much easier to spot errors
Missing a " } ". The usual culprit :) Thanks for your help Theo!
Ah glad to hear it was something simple 😊
|

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.