使用 Get-ChildItem -Exclude 或 -Include returns nothing
Using Get-ChildItem -Exclude or -Include returns nothing
我的 C: 目录中有一个包含很多文件的列表。如果我尝试 运行 对其进行 -Exclude,我不会得到 returns。与 -Include 相同。如果我使用过滤器 returns 我期望得到的结果。我不明白它应该做什么吗?
这是我 运行宁却一无所获的例子:
Get-ChildItem -Path C: -Exclude "*.txt"
我一无所获。如果我运行
Get-Childitem -filter "*.txt"
我回来了:
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
Get-ChildItem -Path "C:\*" -Include "*.txt"
这个关于 -Include
应该如何工作的示例将为您提供您期望的结果。请注意,我还在路径参数中提供了一个通配符,以将路径明确定义为 "any file in the root C:" 而不是 "C:" 本身。
来源:
https://technet.microsoft.com/library/hh849800.aspx
此 link 中的示例 3,以防它失效(也请注意此处路径中的通配符):
C:\> Get-ChildItem –Path "C:\Windows\Logs\*" -Include "*.txt" -Exclude "A*"
使用 'C:' 后没有斜杠是您没有得到想要的结果的原因。这被解释为当前目录的相对路径,而不是 C 驱动器的根目录。 (参见:Path with no slash after drive letter and colon - what does it point to?)
如果您改用 'C:\',它应该可以正常工作。
编辑:我的错误;我专门针对仅使用“-exclude”的示例做出回应。
总结和补充 and 有用的答案:
您的方法有两个明显的问题:
定位 C:
可能不会(总是)做你想做的事,因为 C:
指的是 无论碰巧是什么当前位置(工作目录)目前在驱动器 C: 上。
- 要定位驱动器 C: 的 根文件夹 ,您必须使用
C:\
,我假设这就是您在本答案其余部分中的意思。
使用 -Exclude
(以及 -Include
)参数,-Recurse
和 -Path
值都不以 \*
经常没有结果。 出乎意料?确实 - 请参阅下文了解更多信息。
- 因此,
Get-Item -Path C:\* -Exclude *.txt
- 请注意从 Get-ChildItem
到 Get-Item
的切换以及 C:\
之后的 *
- 需要使您的命令适用于项目 直接 仅在 C:\
中。
背景资料:
使用provider-native -Filter
参数通常优于-Include
,因为:
它比 -Include
快得多,因为提供程序本身在源头执行过滤,而不是让 PowerShell 应用过滤器稍后,所有objects都收到后
不需要您切换到 Get-Item
并将 \*
附加到 -Path
参数值。
例如,Get-ChildItem -Path C:\ -Filter *.txt
可以很好地匹配 C: 根目录中的所有 *.txt
文件。
也就是说,有注意事项:
-Filter
支持的通配符模式语言的功能少于 PowerShell 的 - 值得注意的是,它不支持字符 sets/ranges 例如 [0-9]
- 可能意外地匹配短 (8.3) 文件名,并且有其他遗留问题 - 请参阅 this well-researched answer 了解详细信息。
-Filter
仅支持 单个 模式,而 -Include
支持多个模式(array 个模式)。
不幸的是,-Filter
始终是 positive(包容性)过滤器,因此不能用于提供以下功能-Exclude
.
-Include
/ -Exclude
与 Get-ChildItem
的实现不直观且有缺陷:
旁注:如果您只使用 one -Include
模式(相对于 -Exclude
),将模式直接附加到 -Path
参数更容易;例如:Get-ChildItem C:\*.txt
tl;dr:
要使用 -Include
/ -Exclude
获得可预测的行为,如果您 不是 也使用 -Recurse
(如果您正在使用-Recurse
,则此解决方法不需要):
# IMPORTANT: Workaround isn't needed if you're using -Recurse.
# * "\*" was appended to the input path
# * Get-*ChildItem* was switched to Get-*Item*
Get-Item C:\path\to\* -Include ...
Get-Item C:\path\to\* -Exclude ...
在 PowerShell (Core) v7+ 中,if 你的输入路径是 literal,您也可以将 Get-ChildItem
与 -LiteralPath
一起使用,而不是(可能位置隐含)-Path
(对当前目录使用 .
):
# IMPORTANT: Works in PowerShell (Core) only.
# Note the use of -LiteralPath.
Get-ChildItem -LiteralPath C:\path\to -Include ...
Get-ChildItem -Literalpath C:\path\to -Exclude ...
在 Windows PowerShell[=290= 中存在 彻底的 bug ] 其中,当使用 -LiteralPath
时,-Include
/ -Exclude
被 悄悄忽略 。这已在(至少)v7.0 的 PowerShell (Core) 中修复(并且可以公平地假设它 不会 被修复在 Windows PowerShell 中,它只会收到 关键 修复。
-Include
和 -Exclude
并不像直觉上预期的那样工作 ,这是 GitHub issue #3304 的主题:
-Include
和 -Exclude
修改 leaf (最后一个)路径组件 -Path
参数,即文件或目录 names 在 file-system 路径的情况下。
这意味着模式首先应用于指定文件夹路径本身的叶组件、在 应用到 child 项目之前 ,如果有的话。
如果输入路径不以\*
结尾且未指定-Recurse
,则含义如下:
-Include
:如果输入路径的最后一个路径组件不匹配-Include
模式,输入路径本身 被排除(不包括),路径的 child 项目从未被查看 - 没有输出。
-Exclude
:类似地,如果输入路径的最后一个路径组件确实匹配-Exclude
模式,输入路径 本身 被排除,并且路径的 child 项目从未被查看 - 没有任何输出。
- 目标 root 目录 - 例如,
Get-ChildItem -Path C:\ -Exclude Windows
) 似乎 完全损坏从 v7.0 开始:它要么根本不产生任何输出,要么在 Unix-like 平台上失败,无论是 -Include
还是 -Exclude
,无论使用何种模式 - 请参阅GitHub issue #11649.
如前所述,如果使用 -Recurse
则问题不会出现,因为 强制 下降到输入路径的子树,即使输入路径本身没有被包含/排除。
除非需要-Recurse
,否则获得预期行为的唯一方法是替换
Get-ChildItem C:\path\to -Include / -Exclude
和
Get-Item C:\path\to\* -Include / -Exclude
- 注意使用 Get-Item
而不是 Get-ChildItem
,并且 \*
附加到 -Path
参数。
- 相比之下,如果您将
Get-ChildItem *
与 -Exclude
结合使用,并且 non-excluded 项中有 个目录,Get-ChildItem
会意外地输出 它们的内容而不是 ;这 不会 发生在 -Include
并且通常不会发生在子目录匹配 通过通配符表达式 (-Path
参数and/or -Filter
参数)。
PowerShell 7.2 的问题总结:
GitHub issue #3304(上面讨论过):-Include
/ -Exclude
模式的违反直觉的应用仅用于输入本身而不是它们的 children .
GitHub issue #11649: Get-ChildItem -Path <rootPath> -Exclude <anyPattern>
意外产生 no 输出(即使 不应排除任何内容,假设排除模式通常应用于输入路径,例如 /
或 c:\
)。
GitHub issue #9126: -Include
/ -Exclude
使用 -Recurse
时意外跟随符号链接。
GitHub issue #8662:性能问题:-Include
/ -Exclude
比使用 Where-Object
过滤的 after-the-fact 慢(!)。 =114=]
一个相关的功能请求是GitHub issue #15159,它建议引入排除子文件夹子树的能力(而不是只排除与模式本身匹配的项目,而不是他们的 children),使用新参数,例如 -ExcludeSubtree
.
示例:-Include
/ -Exclude
的有问题的使用
注意:要使下面的所有命令都像人们直观预期的那样工作,请将 Get-ChildItem C:\Windows
替换为 Get-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*
这似乎是一个错误(因为父属性的字符串版本是空字符串?)。使用子目录,它工作正常:
get-childitem c:\windows -directory -exclude *.dll
您可以用不同的方式指定根目录,并得到一个奇怪的错误信息:
get-childitem Microsoft.PowerShell.Core\FileSystem::C:\ -exclude *.txt
get-childitem : Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.
At line:1 char:1
+ get-childitem Microsoft.PowerShell.Core\FileSystem::C:\ -exclude wind ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetChildItemCommand
或者,在osx中:
get-childitem / -directory -exclude *.txt
get-childitem : Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.
At line:1 char:1
+ get-childitem / -directory -exclude var
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetChildItemCommand
这是 powershell 6 及更高版本的解决方法:
get-item c:\ | get-childitem -exclude *.txt
我的 C: 目录中有一个包含很多文件的列表。如果我尝试 运行 对其进行 -Exclude,我不会得到 returns。与 -Include 相同。如果我使用过滤器 returns 我期望得到的结果。我不明白它应该做什么吗?
这是我 运行宁却一无所获的例子:
Get-ChildItem -Path C: -Exclude "*.txt"
我一无所获。如果我运行
Get-Childitem -filter "*.txt"
我回来了:
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
Get-ChildItem -Path "C:\*" -Include "*.txt"
这个关于 -Include
应该如何工作的示例将为您提供您期望的结果。请注意,我还在路径参数中提供了一个通配符,以将路径明确定义为 "any file in the root C:" 而不是 "C:" 本身。
来源: https://technet.microsoft.com/library/hh849800.aspx
此 link 中的示例 3,以防它失效(也请注意此处路径中的通配符):
C:\> Get-ChildItem –Path "C:\Windows\Logs\*" -Include "*.txt" -Exclude "A*"
使用 'C:' 后没有斜杠是您没有得到想要的结果的原因。这被解释为当前目录的相对路径,而不是 C 驱动器的根目录。 (参见:Path with no slash after drive letter and colon - what does it point to?)
如果您改用 'C:\',它应该可以正常工作。
编辑:我的错误;我专门针对仅使用“-exclude”的示例做出回应。
总结和补充
您的方法有两个明显的问题:
定位
C:
可能不会(总是)做你想做的事,因为C:
指的是 无论碰巧是什么当前位置(工作目录)目前在驱动器 C: 上。- 要定位驱动器 C: 的 根文件夹 ,您必须使用
C:\
,我假设这就是您在本答案其余部分中的意思。
- 要定位驱动器 C: 的 根文件夹 ,您必须使用
使用
-Exclude
(以及-Include
)参数,-Recurse
和-Path
值都不以\*
经常没有结果。 出乎意料?确实 - 请参阅下文了解更多信息。- 因此,
Get-Item -Path C:\* -Exclude *.txt
- 请注意从Get-ChildItem
到Get-Item
的切换以及C:\
之后的*
- 需要使您的命令适用于项目 直接 仅在C:\
中。
- 因此,
背景资料:
使用provider-native -Filter
参数通常优于-Include
,因为:
它比
-Include
快得多,因为提供程序本身在源头执行过滤,而不是让 PowerShell 应用过滤器稍后,所有objects都收到后不需要您切换到
Get-Item
并将\*
附加到-Path
参数值。-
例如,
Get-ChildItem -Path C:\ -Filter *.txt
可以很好地匹配 C: 根目录中的所有*.txt
文件。
也就是说,有注意事项:
-Filter
支持的通配符模式语言的功能少于 PowerShell 的 - 值得注意的是,它不支持字符 sets/ranges 例如[0-9]
- 可能意外地匹配短 (8.3) 文件名,并且有其他遗留问题 - 请参阅 this well-researched answer 了解详细信息。-Filter
仅支持 单个 模式,而-Include
支持多个模式(array 个模式)。
不幸的是,-Filter
始终是 positive(包容性)过滤器,因此不能用于提供以下功能-Exclude
.
-Include
/ -Exclude
与 Get-ChildItem
的实现不直观且有缺陷:
旁注:如果您只使用 one -Include
模式(相对于 -Exclude
),将模式直接附加到 -Path
参数更容易;例如:Get-ChildItem C:\*.txt
tl;dr:
要使用 -Include
/ -Exclude
获得可预测的行为,如果您 不是 也使用 -Recurse
(如果您正在使用-Recurse
,则此解决方法不需要):
# IMPORTANT: Workaround isn't needed if you're using -Recurse.
# * "\*" was appended to the input path
# * Get-*ChildItem* was switched to Get-*Item*
Get-Item C:\path\to\* -Include ...
Get-Item C:\path\to\* -Exclude ...
在 PowerShell (Core) v7+ 中,if 你的输入路径是 literal,您也可以将 Get-ChildItem
与 -LiteralPath
一起使用,而不是(可能位置隐含)-Path
(对当前目录使用 .
):
# IMPORTANT: Works in PowerShell (Core) only.
# Note the use of -LiteralPath.
Get-ChildItem -LiteralPath C:\path\to -Include ...
Get-ChildItem -Literalpath C:\path\to -Exclude ...
在 Windows PowerShell[=290= 中存在 彻底的 bug ] 其中,当使用
-LiteralPath
时,-Include
/-Exclude
被 悄悄忽略 。这已在(至少)v7.0 的 PowerShell (Core) 中修复(并且可以公平地假设它 不会 被修复在 Windows PowerShell 中,它只会收到 关键 修复。-Include
和-Exclude
并不像直觉上预期的那样工作 ,这是 GitHub issue #3304 的主题:-Include
和-Exclude
修改 leaf (最后一个)路径组件-Path
参数,即文件或目录 names 在 file-system 路径的情况下。这意味着模式首先应用于指定文件夹路径本身的叶组件、在 应用到 child 项目之前 ,如果有的话。
如果输入路径不以
\*
结尾且未指定-Recurse
,则含义如下:-Include
:如果输入路径的最后一个路径组件不匹配-Include
模式,输入路径本身 被排除(不包括),路径的 child 项目从未被查看 - 没有输出。-Exclude
:类似地,如果输入路径的最后一个路径组件确实匹配-Exclude
模式,输入路径 本身 被排除,并且路径的 child 项目从未被查看 - 没有任何输出。- 目标 root 目录 - 例如,
Get-ChildItem -Path C:\ -Exclude Windows
) 似乎 完全损坏从 v7.0 开始:它要么根本不产生任何输出,要么在 Unix-like 平台上失败,无论是-Include
还是-Exclude
,无论使用何种模式 - 请参阅GitHub issue #11649.
- 目标 root 目录 - 例如,
如前所述,如果使用
-Recurse
则问题不会出现,因为 强制 下降到输入路径的子树,即使输入路径本身没有被包含/排除。
除非需要
-Recurse
,否则获得预期行为的唯一方法是替换
Get-ChildItem C:\path\to -Include / -Exclude
和
Get-Item C:\path\to\* -Include / -Exclude
- 注意使用Get-Item
而不是Get-ChildItem
,并且\*
附加到-Path
参数。- 相比之下,如果您将
Get-ChildItem *
与-Exclude
结合使用,并且 non-excluded 项中有 个目录,Get-ChildItem
会意外地输出 它们的内容而不是 ;这 不会 发生在-Include
并且通常不会发生在子目录匹配 通过通配符表达式 (-Path
参数and/or-Filter
参数)。
- 相比之下,如果您将
PowerShell 7.2 的问题总结:
GitHub issue #3304(上面讨论过):
-Include
/-Exclude
模式的违反直觉的应用仅用于输入本身而不是它们的 children .GitHub issue #11649:
Get-ChildItem -Path <rootPath> -Exclude <anyPattern>
意外产生 no 输出(即使 不应排除任何内容,假设排除模式通常应用于输入路径,例如/
或c:\
)。GitHub issue #9126:
-Include
/-Exclude
使用-Recurse
时意外跟随符号链接。GitHub issue #8662:性能问题:
-Include
/-Exclude
比使用Where-Object
过滤的 after-the-fact 慢(!)。 =114=]一个相关的功能请求是GitHub issue #15159,它建议引入排除子文件夹子树的能力(而不是只排除与模式本身匹配的项目,而不是他们的 children),使用新参数,例如
-ExcludeSubtree
.
示例:-Include
/ -Exclude
的有问题的使用
注意:要使下面的所有命令都像人们直观预期的那样工作,请将 Get-ChildItem C:\Windows
替换为 Get-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*
这似乎是一个错误(因为父属性的字符串版本是空字符串?)。使用子目录,它工作正常:
get-childitem c:\windows -directory -exclude *.dll
您可以用不同的方式指定根目录,并得到一个奇怪的错误信息:
get-childitem Microsoft.PowerShell.Core\FileSystem::C:\ -exclude *.txt
get-childitem : Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.
At line:1 char:1
+ get-childitem Microsoft.PowerShell.Core\FileSystem::C:\ -exclude wind ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetChildItemCommand
或者,在osx中:
get-childitem / -directory -exclude *.txt
get-childitem : Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.
At line:1 char:1
+ get-childitem / -directory -exclude var
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetChildItemCommand
这是 powershell 6 及更高版本的解决方法:
get-item c:\ | get-childitem -exclude *.txt