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

Ric*_*ons 10 powershell get-childitem

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

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

首先,创建一个名为Test [123]somewhere 的文件夹.在该文件夹中,创建几个文件.我的是caled Test1.txtTest2.txt.他们不需要任何东西.

接下来,打开PowerShell会话并打开新文件夹Set-Location父文件Test [123]夹.

现在,运行gci -Filter Test*,你应该看到类似的东西:

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       11/15/2015   3:22 PM                Test [123]
Run Code Online (Sandbox Code Playgroud)

一切都好,对吗?接下来,试试gci -Filter Test* | gci.这使得第一个gci的输出成为下一个gci的输入,即向我们显示第一个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
Run Code Online (Sandbox Code Playgroud)

再次,一切都很好 - 正如预期的那样.这是我们Test [123]文件夹中的所有文件.

现在试试这个:gci -Filter Test* | gci -Recurse.我们所有改变的是第二次调用gci现在是递归的,所以它应该向我们显示包括子文件夹在内的所有文件.我们没有任何子文件夹,所以我们期待相同的结果,对吧?

错误.我们根本没有得到任何输出.似乎非常奇怪,我们所做的一切都已添加-Recurse,现在我们得到了不同的输出.我认为添加-Recurse应该永远不会减少输出,只是更多.

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

Test1.txt
Test2.txt
Run Code Online (Sandbox Code Playgroud)

这已经得到了被打破,对吧?首先-Recurse应该永远不要减少输出量,其次要求不同格式的输出不应该改变我们得到的输出量.

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

我的研究引导我-LiteralPath参数; 但是,将上述命令gci -Filter Test* | foreach { gci -Recurse -LiteralPath $_ }改为,以便使用该参数仍然不返回任何输出,并且再次添加-Name参数会再次启动返回的文件.

我已经设法为此做了一个解决方法,使用-Name参数,然后将它与我正在搜索的文件夹的路径相结合,然后将其传递给Get-Item,但这使得代码更长,更难以实现.

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

Cha*_*ynt 8

TL;DR:-LiteralPath当名称中可能存在不常见字符(包括方括号)时,用于文件夹。


我无法按照 PowerShell v5.1.17134.590 中的 OP 重现此问题。

但是,我能够重现类似的内容,使用以下命令尝试列出我怀疑为空的文件夹中的文件,以便将其删除。事实上,这个文件夹.mp3里有12个文件:

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

[PS]>
Run Code Online (Sandbox Code Playgroud)

添加-Recurse开关会导致 cmdlet 返回错误,而不是上面显示的(误导性的)空响应。我用选项测试了相同的命令-Include *,仍然没有结果,但是这次与开关结合时没有错误-Recurse

-文字路径

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

[PS]> gci -LiteralPath '.\Music\Artist - Name\Album Name [Disc 1]\'
Run Code Online (Sandbox Code Playgroud)

逃跑

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

[PS]> [System.Management.Automation.WildcardPattern]::Escape('.\Music\Artist - Name\Album Name [Disc 1]\')

.\Music\Artist - Name\Album Name `[Disc 1`]\
Run Code Online (Sandbox Code Playgroud)

遗憾的是,这并没有立即奏效。我发现我需要转义两次,然后以下命令给出了正确的目录列表:

[PS]> gci '.\Music\Artist - Name\Album Name ``[Disc 1``]\'
Run Code Online (Sandbox Code Playgroud)

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


Rom*_*min 5

它看起来像这里报告的错误或非常类似的问题.

  • 这看起来像是同一个bug,我相信它已经在Win10的11月份更新中修复了. (2认同)