17

这是我到目前为止所拥有的:

Get-ChildItem "C:\Folder" | Foreach-Object {$_.Name} > C:\Folder\File.txt

当您从上面打开输出 File.txt 时,您会看到:

file1.txt
file2.mpg
file3.avi
file4.txt

如何获得输出,以便它删除扩展名并仅显示以下内容:

file1
file2
file3
file4

提前致谢!

编辑

在我下面的伙伴的帮助下想通了。我最终使用:

Get-ChildItem "C:\Folder" | Foreach-Object {$_.BaseName} > C:\Folder\File.txt
4

5 回答 5

23
Get-ChildItem "C:\Folder" | Select BaseName > C:\Folder\File.txt
于 2012-11-13T22:39:11.947 回答
4

将文件名传递给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()只是它利用了已经计算的扩展

于 2012-11-13T22:38:28.877 回答
2

现在是 FileInfo 版本,因为其他人都比我打败了 Path.GetFileNameWithoutExtension 解决方案。

Get-ChildItem "C:\" | `
where { ! $_.PSIsContainer } | `
Foreach-Object {([System.IO.FileInfo]($_.Name)).Name.Split('.')[0]}
于 2012-11-13T22:57:48.810 回答
1

使用 BaseName 属性而不是 Name 属性:

Get-ChildItem "C:\Folder" | Select-Object BaseName > C:\Folder\File.txt
于 2012-11-13T22:39:28.433 回答
1
(ls).BaseName > C:\Folder\File.txt
于 2022-01-14T07:53:20.573 回答