1

I tried the code found here without success.

What I need is to replace an exact text with another, but this code doesn't seem to deal with exact text.

This is the code I used, and what I need is, for example, for a file name that ends with ".L.wav" to be replaced with "_L.wav", but what happens is that powershell tries to rename even the file that ends with ".BL.wav" into "_L.wav".

Thank you.

ls *.* | Rename-Item -NewName {$_.name -replace ".L.wav","_L.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".LFE.wav","_LFE.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".R.wav","_R.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".BL.wav","_LSR.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".BR.wav","_RSR.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".SL.wav","_LSS.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".SR.wav","_RSS.wav"}
Read-Host -Prompt "Press Enter to exit" ```
Compo
  • 36,585
  • 5
  • 27
  • 39
winoni71
  • 13
  • 4
  • 2
    I have removed your [[tag:batch-file]] tag. Your linked question and answer, as well as everything you've posted, does not mention or imply a Windows batch file with an extension of `.bat` or `.cmd`. Please do not use tags which will waste the time of those who are specifically watching those, a batch file scripter for instance, may have no idea whatsoever about scripting with PowerShell. – Compo Aug 06 '21 at 20:07

1 Answers1

3

The dot in regex means Any Character. Without escaping that, things go wrong.

Try

Rename-Item -NewName {$_.Name -replace ('{0}$' -f [regex]::Escape('.L.wav')),'_L.wav'}

or manually escape the regex metacharacters:

Rename-Item -NewName {$_.Name -replace '\.L\.wav$','_L.wav'}

The $ at the end anchors the text to match at the end on the string

Also, instead of doing ls *.* | Rename-Item {...}, better use

(Get-ChildItem -Filter '*.L.wav' -File) | Rename-Item {...}

(ls is alias to Get-ChildItem )

  • Using the -Filter you can specify what files you're looking for.
  • Using the -File switch, you make sure you do not also try to rename folder objects.
  • By surrounding the Get-ChildItem part of the code in brackets, you make sure the gathering of the files is complete before you start renaming them. Otherwise, chances are the code will try and keep renaming files that are already processed.
Theo
  • 57,719
  • 8
  • 24
  • 41
  • I didn't know about your last point, so you could end up with an endless loop ? – Santiago Squarzon Aug 06 '21 at 20:17
  • 1
    @SantiagoSquarzon Well, probably not endless, but this is a 'gotcha' when using Get-ChildItem and immediately start renaming the files while iterating them through the pipeline. The next iteration, Get-ChildItem sees the altered files as 'new' and passes them through again. Using brackets is one way of stopping that. You could also do `$thefiles = Get-ChildItem ...` and then loop through using `foreach ($file in $thefiles){...}` – Theo Aug 06 '21 at 20:21
  • 1
    @SantiagoSquarzon Of course, you wouldn't need that if you renamed them in such a way that the `-Filter` will not accept them, but it is easy enough to get weird results.. – Theo Aug 06 '21 at 20:27
  • Thank you @Theo, I tried this and it worked perfectly right away. `(Get-ChildItem -Filter '*.L.wav' -File) | Rename-Item -NewName {$_.Name -replace ('{0}$' -f [regex]::Escape('.L.wav')),'_L.wav'}` – winoni71 Aug 06 '21 at 20:46