将文件名传递给GetFileNameWithoutExtension
方法以删除扩展名:
Get-ChildItem "C:\Folder" | `
ForEach-Object { [System.IO.Path]::GetFileNameWithoutExtension($_.Name) } `
> C:\Folder\File.txt
我想评论@MatthewMartin 的答案,它将传入的文件名拆分为.
字符并返回结果数组的第一个元素。这将适用于零或一的名称.
,但会产生不正确的结果:
file.ext1.ext2
产量file
powershell.exe is good for me. Let me explain to thee..doc
产量powershell
原因是它返回了first .
之前的所有内容,而实际上它应该是last .
之前的所有内容。为了解决这个问题,一旦我们将名称拆分为由 分隔的段.
,我们将获取除最后一个以外的每个段,并将它们重新连接在一起,并由 分隔.
。在名称不包含 a 的情况下,.
我们返回整个名称。
ForEach-Object {
$segments = $_.Name.Split('.')
if ($segments.Length -gt 1) {
$segmentsExceptLast = $segments | Select-Object -First ($segments.Length - 1)
return $segmentsExceptLast -join '.'
} else {
return $_.Name
}
}
一种更有效的方法是逐个字符地向后遍历名称。如果当前字符是 a .
,则返回名称直到但不包括当前字符。如果没有.
找到,则返回整个名称。
ForEach-Object {
$name = $_.Name;
for ($i = $name.Length - 1; $i -ge 0; $i--) {
if ($name[$i] -eq '.') {
return $name.Substring(0, $i)
}
}
return $name
}
该类已经提供了一个方法来做同样的事情[String]
,所以上面可以简化为......
ForEach-Object {
$i = $_.Name.LastIndexOf([Char] '.');
if ($i -lt 0) {
return $_.Name
} else {
return $_.Name.Substring(0, $i)
}
}
所有这三种方法都适用于具有零个、一个或多个.
字符的名称,但是,当然,它们也比其他答案更冗长。实际上,LastIndexOf()
是什么GetFileNameWithoutExtension()
在BaseName
内部使用,而使用在功能上与调用相同,$_.Name.Substring()
只是它利用了已经计算的扩展。