Reputation: 5697
I need to extract file name and extension from e.g. my.file.xlsx. I don't know the name of file or extension and there may be more dots in the name, so I need to search the string from the right and when I find first dot (or last from the left), extract the part on the right side and the part on the left side from that dot.
How?
Upvotes: 145
Views: 352124
Reputation: 657
UPDATE: I have since discovered [IO.FileInfo]
as detailed in the answer by @JaquelineVanek and now prefer that method to the -split method below
if [System.IO.Path]::GetFileNameWithoutExtension()
is hard to type or remember:
("file.name.ext.w..dots.ext" -split '\.' | select -SkipLast 1) -join '.'
# >> file.name.ext.w..dots
"file.name.ext.w..dots.ext" -split '\.' | select -Last 1
# >> ext
Notes:
-split
takes a regex (by default) so the .
has to be escaped
I don't think there's a "locale" name.ext filename separator, is there?
-SkipLast
was added in v5.0
The .NET function [System.IO.Path]::GetExtension()
returns the extension including the '.' char; the above returns it without
having to -rejoin the string after splitting could change the result, I suppose, in unusual circumstances. Or if you're uncomfortable re-joining a string that's already joined, one could:
$file = "file.name.ext.w..dots.ext"
$ext = $file -split '\.' | select -Last 1
$name = $file.Substring(0, $file.LastIndexOf(".$ext"))
Upvotes: 2
Reputation: 4719
Let $filePath
be the file complete path, you can extract the extension with this command :
ls $filePath | % Extention
or with this command :
(ls $filePath).Extention
Upvotes: 0
Reputation: 5749
split-path
has a -leaf
flag, which will extract the file name and extension from a given path.
PS C:\Windows\System32\WindowsPowerShell\v1.0>split-path "H:\Documents\devops\tp-mkt-SPD-38.4.10.msi" -leaf
tp-mkt-SPD-38.4.10.msi
PS C:\Windows\System32\WindowsPowerShell\v1.0> $psversiontable
Name Value
---- -----
CLRVersion 2.0.50727.5477
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
Upvotes: 24
Reputation: 377
As of PowerShell 6.0, Split-Path
has an -Extenstion
parameter. This means you can do:
$path | Split-Path -Extension
or
Split-Path -Path $path -Extension
For $path = "test.txt"
both versions will return .txt
, inluding the full stop.
Upvotes: 2
Reputation: 17472
just do it:
$file=Get-Item "C:\temp\file.htm"
$file.Basename
$file.Extension
Upvotes: 35
Reputation: 516
Use Split-Path
$filePath = "C:\PS\Test.Documents\myTestFile.txt";
$fileName = (Split-Path -Path $filePath -Leaf).Split(".")[0];
$extension = (Split-Path -Path $filePath -Leaf).Split(".")[1];
Upvotes: 17
Reputation: 1133
PS C:\Users\joshua> $file = New-Object System.IO.FileInfo('file.type')
PS C:\Users\joshua> $file.BaseName, $file.Extension
file
.type
Upvotes: 10
Reputation: 1
This is an adaptation, if anyone is curious. I needed to test whether RoboCopy successfully copied one file to multiple servers for its integrity:
$Comp = get-content c:\myfile.txt
ForEach ($PC in $Comp) {
dir "\\$PC\Folder\Share\*.*" | Select-Object $_.BaseName
}
Nice and simple, and it shows the directory and the file inside it. If you want to specify one file name or extension, just replace the *'s with whatever you want.
Directory: \\SERVER\Folder\Share
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2/27/2015 5:33 PM 1458935 Test.pptx
Upvotes: 0
Reputation: 60918
If is from a text file and and presuming name file are surrounded by white spaces this is a way:
$a = get-content c:\myfile.txt
$b = $a | select-string -pattern "\s.+\..{3,4}\s" | select -ExpandProperty matches | select -ExpandProperty value
$b | % {"File name:{0} - Extension:{1}" -f $_.substring(0, $_.lastindexof('.')) , $_.substring($_.lastindexof('.'), ($_.length - $_.lastindexof('.'))) }
If is a file you can use something like this based on your needs:
$a = dir .\my.file.xlsx # or $a = get-item c:\my.file.xlsx
$a
Directory: Microsoft.PowerShell.Core\FileSystem::C:\ps
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 25/01/10 11.51 624 my.file.xlsx
$a.BaseName
my.file
$a.Extension
.xlsx
Upvotes: 14
Reputation: 24340
If the file is coming off the disk and as others have stated, use the BaseName
and Extension
properties:
PS C:\> dir *.xlsx | select BaseName,Extension
BaseName Extension
-------- ---------
StackOverflow.com Test Config .xlsx
If you are given the file name as part of string (say coming from a text file), I would use the GetFileNameWithoutExtension
and GetExtension
static methods from the System.IO.Path class:
PS C:\> [System.IO.Path]::GetFileNameWithoutExtension("Test Config.xlsx")
Test Config
PS H:\> [System.IO.Path]::GetExtension("Test Config.xlsx")
.xlsx
Upvotes: 212
Reputation: 126732
Check the BaseName and Extension properties of the FileInfo object.
Upvotes: 8