1

I am trying to rename or remove part of a filename. I have a scheduled job that moves an updated file from one server to another. Once the file is moved it need to be renamed. For example: Filename_01-23-AB.exe to Filename.exe I want to remove everything from the "_" to the "." and leave the extension intact. I found the following code that should do this but I can't seem to get it to work. Am I headed down the right path here?

## Removes the build number from the filename of "Filename_XX-XX-XX.exe" leaving the new filename to be "Filename.exe" ##

$File = -Path "C:\Temp\TestPath\"

foreach ($File in gci *.exe) {
    $Fname = ($File.name).split('.')[0]  ## item before the '.' ##
    $Prefix = $Fname.split('_')[0] ## item before the '_' ##
    $Newname = $Prefix + '.exe'
    Rename-Item $file $Newname 
}
Frode F.
  • 52,376
  • 9
  • 98
  • 114
WastedLoad
  • 23
  • 1
  • 4

3 Answers3

1

I've tried simplifying what you're tying to do:

pushd "C:\Temp\TestPath\"
dir | ? { $_.Name -like "*.exe" } | 
% { Rename-Item $_ "$($_.BaseName.split('_')[0])$($_.Extension)" }
popd

First, this changes the directory your PowerShell is looking at to your defined directory (pushd). Then it will get the contents of your directory, find all objects with the extension of .exe, and split the file's base name at the underscore. popd will then set the directory back to where-ever it was previous to running this script.

Matt
  • 1,230
  • 16
  • 19
1

I think this can be simplifyed even more using a regex to remove everything between the first underscore and the file extension:

$Path= 'C:\Temp\TestPath\'
Get-ChildItem $Path -Filter "*_*.exe" | foreach {
    $_ | Rename-Item -NewName ($_.Name -replace '(?=_).+(?=\.)')
}

This also works when the filename doesn't contain an underscore.

And here the regex demo.

Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
  • `"hello world".Split("_")[0] -eq 'hello world'` :-) – Frode F. May 20 '16 at 16:47
  • Rename-Item : Source and destination path must be different. At line:3 char:21 + $_ | Rename-Item <<<< -NewName ($_.Name -replace '(?=_).+(?=\.)') + CategoryInfo : WriteError: (C:\Temp\TestPath\.#ext:String) [Rename-Item], IOException + FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand – WastedLoad May 20 '16 at 16:47
  • That's because you're finding files that doesn't contain an underscore. Filter out those first, ex. `Get-childItem -Path $path -Filter "*_*.exe" | Foreach { ....` – Frode F. May 20 '16 at 16:49
  • 1
    It may be worth mentioning that this solution will rename any files found, not just .exes. – Matt May 20 '16 at 16:53
  • You are right @FrodeF. I will also edit my answer and use your filter, thanks! – Martin Brandl May 20 '16 at 17:21
0

!not tested

try this

$path = 'C:\Temp\TestPath\'

gci $path *.exe | ? basename -match '_' | % {
    # if the file.txt already exists, rename it to file-1.txt and so on
    $num = 1
    $base = $_.basename.substring(0, $_.basename.indexof('_'))
    $ext = $_.extension
    $dir = $_.directory
    $newname = Join-Path $dir "$base$ext"
    while (Test-Path $newname) {
        $newname = Join-Path $dir "$base-$num$ext"
        $num++
    }

    # finally, rename the file
    ren $_.fullname $newname
}
Community
  • 1
  • 1
Anthony Stringer
  • 1,981
  • 1
  • 10
  • 15
  • Exception calling "Substring" with "2" argument(s): "Length cannot be less than zero. Parameter name: length" At line:6 char:34 + $base = $_.basename.substring <<<< (0, $_.basename.indexof('_')) + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException – WastedLoad May 20 '16 at 16:19
  • updated. i believe that error may have been caused by attempting to rename a file that does not have an `_` in the name – Anthony Stringer May 20 '16 at 17:12