I am trying to use PS to rename a bunch files within a big share and one of the requirements is to remove a dot from the file name. I have tested a few things with my rather basic skills and of course the most basic of scripts zap the file extension.
I finally came up with something like this:
gci *.xlsx | rename-item -newname {$_.Name.replace(".","") $_.extension }
But that adds the extension to the end of the filename (while keeping the file extension intact)
I thought I could zap the last four symbols using something like this:
gci *.xlsx | rename-item -newname { $_.basename.substring(0,$_.basename.length-4) $_.extension }
Overall this seems like an overly complicated operation which could also mess up files without dots (unless I specify xlsx as only 4 symbols to be removed)
Would anyone be able to point me in the right direction to an easier solution? ;-)
CodePudding user response:
You were on the right track with your second attempt: using the .BaseName
and .Extension
properties of the [System.IO.FileInfo]
instances[1] output by Get-ChildItem
allows you to modify the base name (the file name without its extension) separately, and then re-append the extension to form the full file name:
Get-ChildItem *.xlsx |
Rename-Item -NewName { ($_.BaseName -replace '\.') $_.Extension } -WhatIf
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.
The above uses the regex-based -replace
operator to remove all .
instances from the base name; because .
is a regex metacharacter (representing any single character), it must be escaped as \.
in order to be used literally.
In this simple case, you could have used the [string]
type's .Replace()
method as well ($_.BaseName.Replace('.', '')
), but -replace
offers more features and has fewer surprises - see this answer for more information.
Case in point: Say you wanted to remove only the first .
from the base name; -replace
allows you to do that as follows (but you couldn't do it with .Replace()
):
'foo.bar.baz' -replace '\.(.*)$', '$1' # -> 'foobar.baz'
[1] .BaseName
isn't a native property of this type; instead, it is a property that PowerShell decorates instances of the type with, using its ETS (Extended Type System).