1

I have some files like

The Fast and the Furious Tokyo Drift   .avi
The Fast and the Furious 1080p  .mkv

I want to rename these filenames in this way

The Fast and the Furious Tokyo Drift.avi
The Fast and the Furious.mkv

But powershell script fails to do this task

I try to run this code

# Specifies the directory containing the files to be renamed
$directory = 'C:\temp\film\test2'

# Ottieni l'elenco dei file nella directory con le estensioni specificate
$files = Get-ChildItem $directory -Include '*.avi', '*.mkv', '*.mp4'

# Initializes a counter for files of the same name
$counter = 1

# Cycle through each file
foreach ($file in $files) {
    # Create a search string that locates all occurrences of the words to be deleted,
    # regardless of the case
    $search = '(?i)\b(ITA|ENG|AC3|BDRip|1080p|X265_ZMachine)\b|\b1080p\b'
    
    # Replace all occurrences of the words to be deleted with an empty string
    $newName = $file.Name -replace $search, ''
    
    # Eliminate double spaces
    $newName = $newName -replace '  ', ' '
    
    # Remove the spaces at the beginning and end of the file name
    # Create the new file name
    $newName = "$($newName.TrimEnd())$($file.Extension)"
    
    # Check if the new filename is already in the directory
    while (Test-Path -Path "$directory\$newName") {
        # If the new file name already exists, add a sequential number to the name
        $newName = "$($file.BaseName)_$counter$($file.Extension)"
        $counter++
    }
    
    # Rename the file to the new name
    Rename-Item -Path $file.FullName -NewName $newName
    
    # Reset the counter for files with the same name
    $counter = 1
}

In summary, the logic of the code is this

  1. Specifies the directory containing the files to be renamed.
  2. Gets the list of files in the directory with the specified extensions using the Get-ChildItem command with the -Include parameter.
  3. Initializes a counter for files of the same name.
  4. Loop through each file in the resulting list.
  5. Create a search string that finds all occurrences of the words to delete, regardless of case.
  6. Replaces all occurrences of the words to be deleted with an empty string.
  7. Eliminate double spaces.
  8. Remove the spaces at the beginning and end of the file name.
  9. Create the new file name.
  10. Check if the new filename is already in the directory. If the new name already exists, add a sequential number to the name.
  11. Rename the file to the new name using the Rename-Item command.
  12. Reset the counter for files with the same name.
7
  • 1
    $file.Name includes the filename extension; try operating on $file.BaseName Commented Dec 28, 2022 at 0:16
  • I change $newName = "$($newName.TrimEnd())$($file.Extension)" into $newName = "$($newName.TrimEnd())$($file.BaseName)" but nothing happens Commented Dec 28, 2022 at 0:48
  • If I edit this string $files = Get-ChildItem $directory -Include '*.avi', '*.mkv', '*.mp4' into $files = Get-ChildItem $directory it renames but also renames all files adding (1) after extension. Why this happens ? In the same folder I have rename.ps1 and with this code edit $files = Get-ChildItem $directory I get rename.ps1 (1) Commented Dec 28, 2022 at 0:54
  • 1
    You're using -Include which is bugged. It requires the use of \* after the path, or -Recurse. So, it should be $directory = 'C:\temp\film\test2\*'. Commented Dec 28, 2022 at 0:55
  • 1
    Filter only supports one item. Commented Dec 28, 2022 at 1:04

1 Answer 1

2

Summarizing the helpful comments:

$files = Get-ChildItem $directory -Include '*.avi', '*.mkv', '*.mp4'

should be either (note the trailing \*, which is needed due to -Include's counterintuitive behavior - see this answer):

# Only match files of interest located directly in $directory
$files = Get-ChildItem $directory\* -Include *.avi, *.mkv, *.mp4

or (no \* needed, because -Recurse is used):

# Match files of interest located in $directory and any of it subdirs.
$files = Get-ChildItem -Recurse $directory -Include *.avi, *.mkv, *.mp4

$newName = $file.Name -replace $search, ''

should be (.BaseName instead of .Name):

$newName = $file.BaseName -replace $search, ''
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.