当输入路径中有方括号时,Get-ChildItem -Recurse是否被破坏?

问题描述 投票:9回答:2

好的,所以我觉得这一定是PowerShell中的一个错误,但我想知道你们是否认为这听起来很糟糕。重现这是一件非常简单的事情,但我可以理解为什么它可能不是一个特别常见的用例。我下面的步骤实际上并不是我的脚本正在做的事情,我实际上正在计算子文件夹的大小 - 我只是将它浓缩到最简单的场景,显示我的问题。

我只在PowerShell 5.0.10240.16384上尝试了这个,但可能很快就有机会在早期版本上测试它[编辑:我现在在PowerShell 2.0上测试了这个,并且该版本中没有出现错误 - 它按预期工作]。只是一个简单的说明 - 我一直使用gci作为Get-ChildItem的缩写。如果您还不知道,这也可以实际输入到PowerShell中。但是问题存在于你使用的别名中。

首先,在某个地方创建一个名为qazxsw poi的文件夹。在该文件夹中,创建几个文件。我叫做qazxsw poi和Test [123]。他们不需要任何东西。

接下来,打开PowerShell会话并将Test1.txt打开到新Test2.txt文件夹的父文件夹。

现在,运行Set-Location,你应该看到类似的东西:

Test [123]

一切都好,对吗?接下来,尝试gci -Filter Test*。这使得第一个gci的输出成为下一个gci的输入,即向我们显示第一个gci返回的每个项目的子项。这给了我们以下内容:

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       11/15/2015   3:22 PM                Test [123]

再次,一切都很好 - 正如预期的那样。这是我们的gci -Filter Test* | gci文件夹中的所有文件。

现在试试这个:Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 11/14/2015 10:21 PM 0 Test1.txt -a---- 11/15/2015 3:55 PM 0 Test2.txt 。我们所有改变的是第二次调用Test [123]现在是递归的,所以它应该向我们展示包括子文件夹在内的所有文件。我们没有任何子文件夹,所以我们期待相同的结果,对吧?

错误。我们根本没有得到任何输出。看起来非常奇怪,我们所做的就是添加了gci -Filter Test* | gci -Recurse,现在我们得到了不同的输出。我认为添加gci不应该只提供更少的输出。

这是下一个奇怪的事情。现在试试-Recurse。除了添加了-Recurse参数之外,这与之前相同。这只是说我们想要相同的输出,除了我们只想要文件名而不是每个项目的完整信息。所以我们可能期待什么。但这不是我们得到的,我们得到这个:

gci -Filter Test* | gci -Recurse -Name

这必须被打破,对吧?首先-Name永远不应该减少输出量,其次要求不同格式的输出不应该改变我们得到的输出量。

仅当文件夹名称中有方括号时才会发生这种情况。如果您创建另一个文件夹,只需调用Test1.txt Test2.txt ,并再次运行上面的所有命令,您将始终看到-Recurse文件夹中的文件。

我的研究引导我进入Test参数;但是,将上述命令改为Test,以便使用该参数,仍然不返回任何输出,并再次添加-LiteralPath参数启动再次返回的文件。

我已经设法为此做了一个解决方法,使用gci -Filter Test* | foreach { gci -Recurse -LiteralPath $_ }参数,然后将它与我正在搜索的文件夹的路径相结合,然后将其传递到-Name,但这使得代码更长,更难以实现。

所以我的问题是,我犯了错误或误解了什么吗?或者这是我应该报告的错误?

powershell get-childitem
2个回答
5
投票

它看起来像一个bug报告-Name或一个非常类似的问题。


1
投票

TL; DR:当名称中可能有异常字符(包括方括号)时,使用Get-Item作为文件夹。


根据PowerShell v5.1.17134.590中的OP,我无法重现这一点。

但是,我能够重现类似的东西,使用以下命令尝试列出我怀疑是空的文件夹中的文件,以便删除它。实际上,这个文件夹中有12个here文件:

-LiteralPath

添加.mp3开关导致cmdlet返回错误而不是上面显示的(误导性)空响应。我使用[PS]> gci '.\Music\Artist - Name\Album Name [Disc 1]\' [PS]> 选项测试了相同的命令,但仍然没有结果,但是这次与-Recurse开关组合时没有错误。

-LiteralPath

对我来说最有效的方法是使用-Include *参数指定路径:

-Recurse

Escaping

要涵盖其他一些可能的情况,您可能想要尝试转义方括号。在OP的评论中使用@PetSerAl的建议你可以尝试这样的事情:

-LiteralPath

可悲的是,这并没有立即起作用。我发现我需要两次转义,然后以下命令给出了正确的目录列表:

[PS]> gci -LiteralPath '.\Music\Artist - Name\Album Name [Disc 1]\'

有关方括号和转义的更多信息,请参阅以下问答:

  • [PS]> [System.Management.Automation.WildcardPattern]::Escape('.\Music\Artist - Name\Album Name [Disc 1]\') .\Music\Artist - Name\Album Name `[Disc 1`]\
© www.soinside.com 2019 - 2024. All rights reserved.