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

时间:2019-03-30 15:50:39

标签: powershell split powershell-v3.0 powershell-v6.0

在Powershell v6中,拆分路径具有-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是否可行?

1 个答案:

答案 0 :(得分:0)

以路径 string 作为输入,简洁而高效-尽管有点晦涩-PowerShell本机解决方案是使用
-replace operator以使用regex提取扩展名:

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'Get-Item建议的一种更快,更灵活的替代方法,正如西奥所指出的,该建议要求文件存在

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

  

Select-Object不可用时,-Extension是否是可行的解决方案?

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

LotPings指出,仅用[-1]索引到.Split()调用的结果中以提取最后一个令牌就更简洁,更快捷。

另外,考虑使用PowerShell的-split运算符代替[string]类型的.Split()方法routinely

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

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

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

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

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