File Output in Powershell without Extension

岁酱吖の 提交于 2019-12-05 00:08:50
Get-ChildItem "C:\Folder" | Select BaseName > C:\Folder\File.txt

Pass the file name to the GetFileNameWithoutExtension method to remove the extension:

Get-ChildItem "C:\Folder" | `
    ForEach-Object { [System.IO.Path]::GetFileNameWithoutExtension($_.Name) } `
    > C:\Folder\File.txt

I wanted to comment on @MatthewMartin's answer, which splits the incoming file name on the . character and returns the first element of the resulting array. This will work for names with zero or one ., but produces incorrect results for anything else:

  • file.ext1.ext2 yields file
  • powershell.exe is good for me. Let me explain to thee..doc yields powershell

The reason is because it's returning everything before the first . when it should really be everything before the last .. To fix this, once we have the name split into segments separated by ., we take every segment except the last and join them back together separated by .. In the case where the name does not contain a . we return the entire name.

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 more efficient approach would be to walk backwards through the name character-by-character. If the current character is a ., return the name up to but not including the current character. If no . is found, return the entire name.

ForEach-Object {
    $name = $_.Name;

    for ($i = $name.Length - 1; $i -ge 0; $i--) {
        if ($name[$i] -eq '.') {
            return $name.Substring(0, $i)
        }
    }

    return $name
}

The [String] class already provides a method to do this same thing, so the above can be reduced to...

ForEach-Object {
    $i = $_.Name.LastIndexOf([Char] '.');

    if ($i -lt 0) {
        return $_.Name
    } else {
        return $_.Name.Substring(0, $i)
    }
}

All three of these approaches will work for names with zero, one, or multiple . characters, but, of course, they're a lot more verbose than the other answers, too. In fact, LastIndexOf() is what GetFileNameWithoutExtension() uses internally, while what BaseName uses is functionally the same as calling $_.Name.Substring() except it takes advantage of the already-computed extension.

And now for a FileInfo version, since everyone else beat me to a Path.GetFileNameWithoutExtension solution.

Get-ChildItem "C:\" | `
where { ! $_.PSIsContainer } | `
Foreach-Object {([System.IO.FileInfo]($_.Name)).Name.Split('.')[0]}

Use the BaseName property instead of the Name property:

Get-ChildItem "C:\Folder" | Select-Object BaseName > C:\Folder\File.txt
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!