1

在 Powershell v6 中,split-path 具有-Extension访问文件扩展名的参数,例如:

$pathToResume = "R:\Work\cover.letter_resume_base.odt"
$extension = Split-Path -Extension $pathtoResume
Write-Output $extension # Will print .odt

但是,Powershell 3 没有提供-Extension参数,但我想出了这个解决方案:

# Notice the period between cover and letter
$pathToResume = "R:\Work\cover.letter_resume_base.odt"
$pathToResumeLeaf = Split-Path -Leaf $pathToResume
$pathToResumeLeafArray = $pathToResumeLeaf.Split(".")

$fileExtension = $pathToResumeLeafArray | Select-Object -Last 1
Write-Output $fileExtension # Will print odt

我仍然得到文件扩展名,但没有句点。无论文件名中有多少个句点或数组的长度,我都会得到相同的输出。

我想不出任何需要期限的情况。如果我想打印带有扩展名的句点,我可以在使用时轻松添加它Write-Output[string]::format()

当不可用Select-Object时,正如我在上面显示的那样是可行的解决方案吗?-Extension

4

1 回答 1

0

使用路径字符串作为输入,一个简洁而高效的 - 虽然有点晦涩 - PowerShell原生解决方案是使用
-replace运算符使用正则表达式提取扩展名:

PS> "R:\Work\cover.letter_resume_base.odt" -replace '^.+(\.[^.]+)$', '$1'
.odt

注意:此解决方案仅在文件路径具有扩展名的情况下才能可靠运行。

或者,正如Theo建议的那样,直接使用 .NET 框架:

PS> [IO.Path]::GetExtension("R:\Work\cover.letter_resume_base.odt")
.odt

您还可以强制转换[System.IO.FileInfo]并访问该.Extension属性:

PS> ([IO.FileInfo] "R:\Work\cover.letter_resume_base.odt").Extension
.odt

以上是LotPings建议的更快、更灵活的替代方案,正如 Theo 所指出的Get-Item,该建议要求文件存在

# Works, but file must exist.
PS> (Get-Item "R:\Work\cover.letter_resume_base.odt").Extension
.odt

Select-Object如上所示,在-Extension不可用时是可行的解决方案吗?

是的,但它冗长且缓慢(尽管在这种情况下性能可能无关紧要),因为与使用涉及操作符的表达式相比,使用管道cmdlet总是会引入开销。

LotPings 指出,简单地将 with 索引[-1].Split()调用结果中以提取最后一个标记既更简洁又更快。

此外,请考虑定期使用 PowerShell 的-split运算符而不是[string]类型的.Split()方法:

PS> '.' + ("R:\Work\cover.letter_resume_base.odt" -split '\.')[-1]
.odt

至于是否保留首字母.作为扩展的一部分:

无论哪种方式,只要您确保在.合成文件名时存在 ,但保留.有两个优点:

  • 查看该值可以明显看出您正在处理扩展

  • 您可以直接将该值附加到文件的基本名称(例如,$baseName + $ext),这也适用于没有扩展名的情况(如果$ext恰好包含空字符串)。

于 2019-03-31T00:06:11.180 回答