当您无权访问 -Extension 时,使用 Select-Object 是否合适?

Is using Select-Object suitable when you don't have access to -Extension?

在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()

时轻松添加它

-Extension 不可用时,Select-Object 是我上面显示的可行解决方案吗?

以路径 string 作为输入,一个简洁且高效的 - 虽然有点晦涩 - PowerShell 原生解决方案是使用
to extract the extension using a regex:

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

注意:此解决方案仅在文件路径 具有 扩展名时才能可靠地工作。

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

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' Get-Item 建议的一种更快、更灵活的替代方案,正如 Theo 指出的那样,该建议要求文件 存在

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

Is Select-Object, as shown above, a viable solution when -Extension is unavailable?

是的,但它冗长且缓慢(尽管在这种情况下性能可能无关紧要),因为使用 pipelinecmdlets[=与使用涉及 operators.

expressions 相比,74=] 总是会引入开销

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

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

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

至于是否保留初始的.作为扩展的一部分:

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

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

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