Get-ChildItem以及包含字符'&' 的文件夹名称所形成的文件夹结构

前端开发 2026-07-09

有这样一个目录结构的基本摘录,文件夹名称里包含一个 &

Music
    - Massive_Attack
        - Collected
        - Mezzanine
        - Protection

      - Massive_Attack_&_Mad_Professor
        -No_Protection

使用PowerShell的 get-childitem

$tree = get-childitem -path "\Music" -recurse -directory -name

$tree 返回的列表中,包含 & 的文件夹位于其他文件夹结构的中间,如 <<< 所示:

Massive_Attack
Massive_Attack/Collected
Massive_Attack_&_Mad_Professor                <<<
Massive_Attack_&_Mad_Professor/No_Protection  <<<
Massive_Attack/Mezzanine
Massive_Attack/Protection

将文件夹重命名,使其拥有一个 V 而不是 &,并再次使用 get-childitem

$tree = get-childitem -path "\Music" -recurse -directory -name

$tree 返回的列表现在已经按预期的顺序排列。

Massive_Attack
Massive_Attack/Collected
Massive_Attack/Mezzanine
Massive_Attack/Protection
Massive_Attack_V_Mad_Professor
Massive_Attack_V_Mad_Professor/No_Protection

已附加 | sort,尽管对于 V& 返回的列表顺序仍然相同。

$tree = get-childitem -path "\Music" -recurse -directory -name | sort

有办法解决吗?

PowerShell 7.6.1(Linux)

非常感谢

解决方案

你可以自行进行递归,按你需要的顺序返回对象:

Function Get-ChildDirRecurse {
[CmdletBinding()]
Param([Parameter(ValueFromPipeline=$true)]$Path)
    Process {
        $Path | Get-ChildItem -Directory | ForEach-Object {
            $_
            $_ | Get-ChildDirRecurse
        }
    }
}

$tree = Get-ChildDirRecurse -Path "/Music" | Select-Object -ExpandProperty FullName
$tree

备选方案

你期望的顺序在字典序上并不正确,那些具有 _ 的应排在那些具有 / 的之前'_'.CompareTo('/') 输出 -1,这意味着 _ 小于 /,因此在升序中应先排在前面。

先不谈这个,你的问题在Windows上无法重现。Sort-Object 确实给出了正确的顺序,请看下方的示例。

如果你在Linux上得到不同的结果,可能是一个bug,或者原因是输入被通过管道传给 GNU sort 而不是 Sort-Object。为确保,可以测试用 Sort-Object 代替 sort

$data = @'
Massive_Attack
Massive_Attack/Collected
Massive_Attack_&_Mad_Professor
Massive_Attack_&_Mad_Professor/No_Protection
Massive_Attack/Mezzanine
Massive_Attack/Protection
'@ -split '\r?\n'

# Generate test data
New-Item test -ItemType Directory | Push-Location
$null = $data | ForEach-Object { New-Item $_ -Force -ItemType Directory }

# Testing
Get-ChildItem -Name -Directory -Recurse | Sort-Object
# Massive_Attack
# Massive_Attack_&_Mad_Professor
# Massive_Attack_&_Mad_Professor\No_Protection
# Massive_Attack\Collected
# Massive_Attack\Mezzanine
# Massive_Attack\Protection

# Cleaning up
Pop-Location
Remove-Item test

要获得你期望的顺序,即将拥有 & 的放在最后,你可以先按长度排序,再按值(字典序)排序:

Get-ChildItem "\Music" -Name -Directory -Recurse |
    Sort-Object { $_.Length }, { $_ }
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章