Powershell 与Get-ChildItem cmdlet的-Include参数混淆
从文件: -包括 仅检索指定的项。 此参数的值符合以下条件: 路径参数。输入路径 元素或模式,如“*.txt”。 允许使用通配符 Include参数仅在命令 包括递归参数或 路径指向 目录,如C:\Windows*,其中 通配符指定 C:\Windows目录的内容 我的第一个理解是:Powershell 与Get-ChildItem cmdlet的-Include参数混淆,powershell,include,get-childitem,Powershell,Include,Get Childitem,从文件: -包括 仅检索指定的项。 此参数的值符合以下条件: 路径参数。输入路径 元素或模式,如“*.txt”。 允许使用通配符 Include参数仅在命令 包括递归参数或 路径指向 目录,如C:\Windows*,其中 通配符指定 C:\Windows目录的内容 我的第一个理解是: c:\test\a.txt c:\test\b.txt 因此,要获得“a.txt”和“b.txt”,我可以写: gci -Path "c:\test\*" -Include "*.txt" 这是有效的。但是现在
c:\test\a.txt
c:\test\b.txt
因此,要获得“a.txt”和“b.txt”,我可以写:
gci -Path "c:\test\*" -Include "*.txt"
这是有效的。但是现在考虑这样的层次:
c:\test\a.txt
c:\test\b.txt
c:\test\c.txt\c.txt
同一命令返回:
a、 txt,b.txt,c.txt
实际逻辑似乎是:
-Include用于匹配-Path指定的所有实体。如果匹配元素
是一个文件-返回它。如果匹配
元素是一个文件夹,请查看内部和外部
返回匹配的第一级子级
此外,文件中说:
Include参数仅在命令
包括递归参数或
路径指向
目录
这也是错误的。例如
gci -Path "c:\test" -Include "*.txt"
它不返回任何内容,而不包含文件夹内容。因此,包含肯定是“有效的”。这里到底发生了什么?-Path指定“c:\test”,而-Include尝试匹配此路径。由于“*.txt”与“test”不匹配,因此没有返回任何内容。但看看这个:
gci -Path "c:\test" -Include "*t"
它将a.txt、b.txt和c.txt返回为“*t”匹配的“test”,并匹配所有子项
毕竟,即使知道Include现在是如何工作的,我也不知道什么时候使用它。为什么我需要它查看子文件夹内部?为什么要这么复杂?您混淆了-include的用法。-include标志应用于路径,而不是路径的内容。如果不使用递归标志,唯一有问题的路径就是您指定的路径。这就是为什么您给出的最后一个示例有效,路径
c:\test
中有一个t,因此匹配“*t”
您可以通过尝试以下操作来验证这一点
gci -path "c:\test" -in *e*
这仍然会生成目录中的所有子项,但它与它们的名称都不匹配
使用recurse参数-include更有效的原因是,最终会对层次结构中的每个路径应用通配符 接着,为了与Get ChildItem进行模式匹配,可以使用公共shell通配符
例如:
get-childitem "c:\test\t?st.txt"
其中“?”是匹配任何一个字符或
get-childitem "c:\test\*.txt"
它将匹配以“.txt”结尾的任何文件名
这将使您获得所需的“更简单”的行为。尝试-filter参数(它只支持一个扩展):
dir-filter*.txt我刚刚问了一个类似的问题,并得到了关于for Get ChildItem的三个快速回复 答案是完整的描述 命令(Get-Help Get-ChildItem)的 -全文): 递归参数或路径指向 目录的内容,例如 C:\Windows*,其中通配符 字符指定文件的内容 C:\Windows目录 因此,以下内容在没有 重现 PS C:\foo>Get childitem-path “c:\foo*”-包含*.txt 从堆栈溢出问题
我希望这有帮助:-)包括路径末尾的
\*
应该可以解决这个问题
PS C:\logfiles> Get-ChildItem .\* -include *.log
这将返回当前工作目录中的.log文件(C:\logfiles
)
上面Alex的示例表明还将返回名为foo.log的目录。当我尝试它时,它不是,但它是6年后,这可能是从PS更新
但是,我认为您可以使用子项模式
来排除目录
PS C:\logfiles> Get-Childitem .\* -include *.log | where-object {$_.mode -notmatch "d"}
这应该排除设置了“目录”模式的任何内容。get childitem-include仅适用于路径中的-recursive或通配符。我认为这是一个bug [认为它在PS 6中是不同的。< 我使用的是PowerShell-v2.0-CTP3,您的示例生成的是空集。@alex2k8,不知道在这里说什么。我在1.0和更高版本的2.0上试过这个例子,两个版本的结果都是一样的。@Jared,这很奇怪。请你试试gci-path c:-in*。我看到c:\及其所有子文件夹的子文件夹向下一层。下面是一个类似的描述过滤器,它略有不同,因为它是一个特定于提供者的实现。它通常更有效,因为它发生在数据返回之前。但对于PowerShell中的每个驱动器提供程序,它都有不同的实现。因此,在匹配算法中可能存在细微的差异。我同意,不过在本例中,我们讨论的是文件系统提供商。谢谢你的评论。这里的问题不就是你只能得到一个扩展吗-Include是允许多个匹配变体的字符串[]。谢谢,本,实际上我的问题有点不同。请注意,您的示例将从foo文件夹返回.txt文件,但它也可能意外地从例如“c:\foo\dir.txt”目录返回文件甚至文件夹。尝试这样的层次结构:c:\foo\dir.txt\file.txt和c:\foo\dir.txt\dir2.txt\file2.txt。您将得到:file.txt和dir2.txt!在路径末尾包含*并不总是有效。我不知道如何指定-Include值来匹配没有文件扩展名的文件。将*指定为-Include模式将匹配这样的文件,但会使Get-ChildItem递归动作。如果-Include的行为方式与Exclude相同,那么就很容易了。事实并非如此,仍然需要添加
\*
才能使其正常工作。
PS C:\logfiles> Get-Childitem .\* -include *.log | where-object {$_.mode -notmatch "d"}