使用Get-ChildItem -Exclude或-Include不返回任何内容

bra*_*ice 6 powershell powershell-4.0

我的C:目录中有一个包含许多文件的列表.如果我尝试在其上运行-Exclude,则不会返回.与-Include相同.如果我使用过滤器,它会返回我期望的结果.我不明白它应该做什么?

以下是我正在运行并且什么都没得到的示例:

Get-ChildItem -Path C: -Exclude "*.txt"
Run Code Online (Sandbox Code Playgroud)

我一无所获.如果我跑

Get-Childitem -filter "*.txt"
Run Code Online (Sandbox Code Playgroud)

我得到了回报:

  Mode                LastWriteTime         Length Name                                                                               
----                -------------         ------ ----                                                                               
-a----        11/7/2007   8:00 AM          17734 eula.1028.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1031.txt                                                                      
-a----        11/7/2007   8:00 AM          10134 eula.1033.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1036.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1040.txt                                                                      
-a----        11/7/2007   8:00 AM            118 eula.1041.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.1042.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.2052.txt                                                                      
-a----        11/7/2007   8:00 AM          17734 eula.3082.txt                                                                      
               7/7/2016   8:50 AM             93 HaxLogs.txt                                                                        
-a----         7/8/2016   8:30 AM              0 Test.txt 
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 15

总结和补充引力Brian Reynolds的有用答案:

您的方法存在两个明显的问题:

  • 定位C:可能不会(总是)做你想要的,因为C:指的是驱动器C上当前位置(工作目录.)的任何事情.

    • 要定位驱动器C:的根文件夹,您必须使用C:\,我将假设您在本答复的其余部分中的含义.
  • 使用-Exclude(和-Include)参数既不使用-Recurse也不以-Path值结尾\*通常会产生NO结果.意外?确实 - 见下文了解更多.

    • 因此,Get-Item -Path C:\* -Exclude *.txt-注意,从交换机Get-ChildItemGet-Item*C:\-使对位于项目的指挥工作需要直接C:\只.

背景资料:

使用provider-native -Filter参数通常比较好-Include,因为:

  • 它比-Include提供者本身在源处执行过滤要快得多,而不是在收到所有对象后让PowerShell 稍后应用过滤器.

  • 它不需要您切换到Get-Item和附加\*-Path参数值.

    • Get-ChildItem -Path C:\ -Filter *.txt例如,可以很好地匹配*.txtC:的根目录中的所有文件.

也就是说,有警告:

  • 支持的通配符模式语言-Filter具有比PowerShell更少的功能,并且可能意外地匹配短(8.3)文件名 - 请参阅这个经过充分研究的答案,了解血腥细节.

  • -Filter仅支持单个模式,而-Include支持多个模式(模式数组).

不幸的是,-Filter始终是一个积极的(包含)过滤器,因此不能用于提供功能-Exclude.


-Include/ -Excludewith 的实现Get-ChildItem是不直观的,并且存在缺陷:

旁注:如果您只使用一个 -Include模式(而不是-Exclude),则更容易将模式直接附加到-Path参数; 例如:Get-ChildItem C:\*.txt

tl; dr:要使用-Include/ 获得可预测的行为-Exclude,请使用Get-Item C:\path\to\*(注意附加\*和切换Get-*Child*Item) - 除非您也使用-Recurse.

  • -Include并且-Exclude不像人们直觉所期望的那样工作:

    • -Include-Exclude修改参数的(最后)路径组件-Path.

    • 这意味着,该模式被应用到的叶组件文件夹路径本身首先,之前得到应用到子项,如果在所有.

    • 如果输入路径不结束\*-Recurse没有被指定,其意义如下:

      • -Include:如果输入路径的最后一个路径组件与模式匹配-Include,则排除(不包括)输入路径本身,并且永远不会查看路径的项 - 不输出任何内容.

      • -Exclude:类似地,如果输入路径的最后一个路径组件匹配-Exclude模式(S),输入路径本身被排除,以及路径的项从来不看-没有什么是输出.

        • 在path C:\(Get-ChildItem -Path C:\ -Exclude <any-pattern>)的特殊情况下,可以说最后一个路径组件是空字符串,似乎任何排除模式都被视为匹配,并且不会产生任何输出.
    • 如上所述,如果-Recurse使用问题,则问题不会浮出水面,因为即使输入路径本身未被包含/排除,也会强制下降到输入路径的子树中.

  • 除非-Recurse需要,否则获得预期行为的唯一方法是替换
    Get-ChildItem C:\path\to -Include / -Exclude
    Get-Item C:\path\to\* -Include / -Exclude- 注意使用Get-Item而不是Get-ChildItem,并且\*附加-Path参数.

    • 相比之下,如果您使用Get-ChildItem并且匹配中有目录,Get-ChildItem则会输出其内容.
  • 随着-LiteralPath而不是-Path,-Include-Exclude悄然忽略 -他们没有任何影响.


示例:-Include/ 有问题的用途-Exclude

注意:要使下面的所有命令按照直观的方式工作,请替换Get-ChildItem C:\WindowsGet-Item C:\Windows\*- 注意使用不同的cmdlet Get-Item,以及附加的\*.

# HAPPENS TO WORK, BUT IS NOT ROBUST:
# Matches all w* items *inside* C:\Windows, but
# ONLY because w* happens to match 'Windows' - the last input
# path component - too.
Get-ChildItem C:\Windows -Include w*

# HAPPENS TO WORK, BUT IS NOT ROBUST:
# Matches all items whose names *don't* start with a-v *inside* C:\Windows, but
# ONLY because [a-v]* happens not to exclude 'Windows' - the last input
# path component - too.
Get-ChildItem C:\Windows -Exclude [a-v]*


# OUTPUTS NOTHING:
# Because t* doesn't match 'Windows', the child items of 
# 'C:\Windows' are not considered.
Get-ChildItem C:\Windows -Include t*

# OUTPUTS NOTHING:
# Because w* matches 'Windows', it is excluded, and
# the child items of 'C:\Windows' are not considered.     
Get-ChildItem C:\Windows -Exclude w*
Run Code Online (Sandbox Code Playgroud)

  • 这是令人难以置信的。它的字面意思是 -Include/-Exclude 已知会被默默地忽略;因此它们是不可靠的。编写带有 -Exclude 选项的脚本来删除子目录是非常危险的,因为它可能会删除它们。这是一个巨大的问题,因为Remove-Item文档说它的-Recurse参数也“已知不起作用”,并建议使用Get-ChildItem将其通过管道传递给命令作为解决方法。但 Get-ChildItem 显然也被破坏了!真是一团糟。 (3认同)
  • 神圣的moly,它完全融入了所有不同的挂起!真正深入挖掘推理的方法!:)你有没有找到这个,或者你自己研究过吗? (2认同)

gra*_*ity 7

Get-ChildItem -Path "C:\*" -Include "*.txt"
Run Code Online (Sandbox Code Playgroud)

这个-Include应该如何工作的例子将给你你期望的结果.请注意,我在path参数中也提供了一个通配符,以明确地将路径定义为"根C:中的任何文件",而不是"C:"本身.

资料来源:https: //technet.microsoft.com/library/hh849800.aspx

示例3来自此链接,以防它失效(请注意此处路径中的通配符):

C:\> Get-ChildItem –Path "C:\Windows\Logs\*" -Include "*.txt" -Exclude "A*"
Run Code Online (Sandbox Code Playgroud)

  • 哇。显然,在路径中添加通配符使一切正常。这太令人困惑了 (3认同)
  • 这就是让我发疯的事情:当 API/命令根据输入以不同的方式运行时。当然,这应该发生,但我的意思是在这种情况下。当您单独传入路径时,它假定通配符 `*`。当您添加 `-Include` 或 `-Exclude` 时,它会停止做出这种假设,并且文档没有说明这一点。更重要的是,该命令称为“Get-ChildItem”。它应该得到儿童项目。在所有情况下都不需要通配符。 (2认同)