【问题标题】:File Output in Powershell without Extension没有扩展名的 Powershell 中的文件输出
【发布时间】:2012-11-13 22:33:34
【问题描述】:

这是我目前所拥有的:

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

【问题讨论】:

  • 因为我一直在寻找一些不同的东西,而谷歌将我带到了这里:如果有人试图只获取没有扩展名的文件,请尝试Get-ChildItem $dir | ? {$_.Extension -ne ""}

标签: powershell powershell-2.0


【解决方案1】:
Get-ChildItem "C:\Folder" | Select BaseName > C:\Folder\File.txt

【讨论】:

  • 感谢您的快速提醒。我这辈子都不记得 BaseName 了。我最终使用了:Get-ChildItem "C:\Folder" | Foreach-Object {$_.BaseName} > C:\Folder\File.txt
  • @CaptHowdy $foo | Get-Member 将显示对象的属性和方法。
  • 如果有人正在寻找当前目录的简写版本,试试这个ls . | Select BaseName
  • 我希望我能喜欢 @ansgar-wiechers 的评论,我似乎总是忘记 Get-Member!
【解决方案2】:

将文件名传递给GetFileNameWithoutExtension method 以删除扩展名:

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

我想评论@MatthewMartin's answer,它将传入的文件名拆分为. 字符并返回结果数组的第一个元素。这将适用于具有零个或一个 . 的名称,但会产生不正确的结果:

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

原因是因为它返回了 first . 之前的所有内容,而实际上它应该是 last . 之前的所有内容。为了解决这个问题,一旦我们将名称拆分为由. 分隔的段,我们将取除最后一个段之外的每个段并将它们重新连接在一起,并由. 分隔。如果名称不包含.,我们将返回整个名称。

ForEach-Object {
    $segments = $_.Name.Split('.')

    if ($segments.Length -gt 1) {
        $segmentsExceptLast = $segments | Select-Object -First ($segments.Length - 1)

        return $segmentsExceptLast -join '.'
    } else {
        return $_.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
}

[String] class 已经提供了a method to do this same thing,所以上面可以简化为...

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

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

所有这三种方法都适用于具有零个、一个或多个. 字符的名称,但是,当然,它们也比其他答案更冗长。事实上,LastIndexOf()what GetFileNameWithoutExtension() uses internally,而what BaseName uses 在功能上与调用$_.Name.Substring() 相同,只是它利用了already-computed extension

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 正是我需要的,我的文件也附加了一些数字。拥有 .split('.') 帮助我切断了所有附加的内容,包括分机。
    • 应该注意的是,删除扩展涉及返回 last . 之前的所有内容,而这将返回 first . 之前的所有内容.对于包含 0 个或 1 个 . 的名称(例如在问题中)没有区别,但对于像 file.ext1.ext2powershell.exe is good for me. Let me explain to thee..doc 这样的名称,它分别返回 filepowershell。我已经用一些方法更新了my answer 来解决这个问题。对了,[System.IO.FileInfo]($_.Name)).Name是多余的,可以简化成$_.Name
    【解决方案4】:

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

    Get-ChildItem "C:\Folder" | Select-Object BaseName > C:\Folder\File.txt
    

    【讨论】:

    • 您可能应该解释原因:Basename 给出的文件名不带扩展名。 Name 属性包含扩展名。
    【解决方案5】:
    (ls).BaseName > C:\Folder\File.txt
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2014-04-24
    • 2016-12-24
    • 2023-03-23
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    • 2020-10-16
    • 2017-06-27
    相关资源
    最近更新 更多