PowerShell,获取具有深度输出的子项
Get ChildItem的PowerShell,获取具有深度输出的子项,powershell,recursion,Powershell,Recursion,Get ChildItem的-Depth标志让我有点困惑。以下操作非常有效(在“C:\Program files”下只查找一个深度的所有文件和文件夹): 但是,如果我想扩展它以只查找*.txt类型的文件,我就找不到如何做(下面给出了奇怪的意外输出,其中忽略了-Depth 1,它相当于对所有子文件夹进行-Recurse,无论其深度有多深): 我们如何将-Depth用于Get ChildItem和所需文件模式的特定深度?当您使用过滤器而不是包含时,问题得到解决。Filter参数将以正确的模式返回文件
-Depth
标志让我有点困惑。以下操作非常有效(在“C:\Program files”下只查找一个深度的所有文件和文件夹):
但是,如果我想扩展它以只查找*.txt类型的文件,我就找不到如何做(下面给出了奇怪的意外输出,其中忽略了-Depth 1
,它相当于对所有子文件夹进行-Recurse
,无论其深度有多深):
我们如何将
-Depth
用于Get ChildItem和所需文件模式的特定深度?当您使用过滤器而不是包含时,问题得到解决。Filter参数将以正确的模式返回文件,并带有深度。(测试)
进一步澄清Wasif Hasan提出的问题
当我通过官方的Get ChildItem时,它在那里被声明了
使用-Include参数时,如果不包含星号
在路径中,命令不返回任何输出
这意味着深度
将被自动忽略,因为包含
所需的行为是递归的。关于-Include的更多细节揭示了这些要点
如果将Recurse参数添加到命令中,则
路径参数中的星号(*)是可选的。递归参数
从路径目录及其子目录获取项。对于
示例,-路径C:\Test \-Recurse-Include*.txt
因此,您要查找的行为位于不需要任何通配符的Get ChildItem
的Filter
标志中
对我来说,Depth
标志和接受路径中通配符的任何其他标志没有意义,因为Depth
标志的目的是限制项目中的搜索深度,因为指定通配符不包括该特定目的。
您只需使用此命令即可尝试此操作,例如,如果在路径中指定通配符,您将看到Depth
参数无效
Get-ChildItem -Path C:\DIRECTORY\* -Depth 1
及
将返回相同的结果
希望这有助于澄清一些问题在旧版本的PowerShell中没有深度,在这种情况下,上述内容也可以
Get-ChildItem -Path "C:\DIRECTORY\*","C:\DIRECTORY\*\*"
如果是纯文件名,那么
(Get-ChildItem -Path "c:\program files" -file -Depth 3 -Force -erroraction SilentlyContinue).FullName
与古代的把戏相同,即
(cmd.exe /c dir "c:\program files" /b /a-d /s)|foreach {if ($_.split("\").length -le 5){$_}}
令人惊讶的是,PowerShell甚至比上面这一行还要快!我记得几年前情况并非如此,但我刚刚测试了它,速度快了3-4倍您看到的行为是Windows PowerShell中的一个错误,该错误已在PowerShell[Core]6+中修复-请参见
鉴于Windows PowerShell不再是主动开发的,因此该漏洞不太可能得到修复
具体来说,Windows PowerShell在以下情况下忽略了-Depth
的深度约束:
- 使用
-包括或-排除
- 如果(隐含的)
-Path
参数包含通配符
当仍然执行递归时,不施加深度限制;实际上,-Depth
在这些情况下的行为类似于-Recurse
(单独)
变通办法:
- 对于
-包括
和基于通配符的-路径
参数,其中通配符仅限于最后一个路径组件:
- 改用
-Filter
,如中所示
- 注意事项:
-过滤器
通常因其卓越的性能而更受欢迎,但其通配符语言不如PowerShell强大,并且有一些遗留问题-值得注意的是,字符集和范围([…]
)不支持,例如,在Windows PowerShell中,诸如*.xls
之类的筛选器也与*.xlsx
文件匹配-请参阅
- 对于
-排除:
- 仅使用
-Depth
,通过调用在事实发生后执行过滤;e、 g.,
Get ChildItem-File'C:\Program Files\'-Depth 1 | Where Object Name-NotLike*.txt
- [可能很少需要]对于基于通配符的
-Path
参数,在除最后一个(例如,C:\foo*\bar
)以外的组件中使用通配符
- 使用
-Recurse
并使用Where Object
在事实之后执行过滤;在这种情况下,还必须通过计算路径组件的数量来剔除太深的路径
是的,谢谢,我还想说这没有道理。给我一个错误,或一个有意义的警告,指出我的语法可能是错误的,不要给我奇怪的意外结果。我看不出有什么理由不能编写Depth
,从而使它在其他情况下按预期运行。一切似乎都有点适得其反。我想知道这个Cmdlet的作者对这个奇怪的输出结果是怎么想的。这个行为是Windows PowerShell中的一个bug,它已经在PowerShell[Core]6+中修复了-请参阅。是的,-Filter
不要求-Path
参数以*
结尾才能生效,但是如果还执行递归,-Include
也不要求生效,并且使用-Depth
意味着-Recurse
。正是这个bug使两个深度不同的C:\DIRECTORY\*
命令输出相同的结果,-Depth
限制再次被忽略。@mklement0同意报告的问题,但不确定为什么-Include
的官方文档声明它需要在路径中使用通配符或将返回empty@DevX,这是由于一个不相关的问题,即不幸的事实是,如果没有递归,-Include
模式(首先)与输入路径本身匹配,这意味着通常没有匹配。将\*
附加到输入路径中会产生
Get-ChildItem -Path C:\DIRECTORY\* -Depth 2
Get-ChildItem -Path "C:\DIRECTORY\*","C:\DIRECTORY\*\*"
(Get-ChildItem -Path "c:\program files" -file -Depth 3 -Force -erroraction SilentlyContinue).FullName
(cmd.exe /c dir "c:\program files" /b /a-d /s)|foreach {if ($_.split("\").length -le 5){$_}}