简体   繁体   English

Powershell Get Child Item Exclude 在当前目录中不起作用

[英]Powershell Get Child Item Exclude doesn't work in current directory

As I mentioned in question, this seems like bug in Powershell engine.正如我所提到的,这似乎是 Powershell 引擎中的错误。

When I try to print the files in the current directory(where the said powershell script is also present) by excluding some file-types(extensions), it doesn't print anything.当我尝试通过排除某些文件类型(扩展名)来打印当前目录(也存在所述 powershell 脚本)中的文件时,它不会打印任何内容。 For eg.例如。 below codes print contents of Current Folder in the Powershell console:以下代码在 Powershell 控制台中打印当前文件夹的内容:

gci
gci -pa .

Both the above codes print the directory contents as below:以上代码打印目录内容如下:

Mode                LastWriteTime         Length Name                                                                                     
----                -------------         ------ ----                                                                                     
-a----       20-09-2020     22:37      835799796 file1.mkv                                                                      
-a----       20-09-2020     22:25            148 file1.srt                                      
-a----       23-09-2020     04:53            357 scriptv1.ps1                                                           
-a----       20-09-2020     22:25            678 file1.txt

But when I run below code, it doesn't print anything, when it must print file1.txt:但是当我运行下面的代码时,它不打印任何东西,当它必须打印 file1.txt 时:

$excluded = @('*.mkv','*.mp4','*.srt','*.sub','*.ps1')
Get-ChildItem -Exclude $excluded | Write-Host { $_.FullName }

Can anyone assist figuring out why is it happening and how to get what I mentioned ?任何人都可以帮助弄清楚为什么会发生这种情况以及如何获得我提到的内容?

The use of -Exclude with Get-ChildItem is not intuitive.-ExcludeGet-ChildItem一起使用并不直观。 To get consistent results with Get-ChildItem , you must qualify your path with \\* or use the -Recurse switch.要使用Get-ChildItem获得一致的结果,您必须使用\\*限定您的路径或使用-Recurse开关。 If you do not care to recurse, you can just use Get-Item with a \\* qualifying the path.如果您不关心递归,您可以使用带有\\*限定路径的Get-Item

# Works but includes all subdirectory searches
Get-ChildItem -Path .\* -Exclude $excluded
Get-ChildItem -Path .\* -Exclude $excluded -File
Get-ChildItem -Path . -Exclude $excluded -File -Recurse

# Best results for one directory
Get-Item -Path .\* -Exclude $excluded

The reason recursion should be used is because -Exclude values are applied to the leaf of -Path value first.应该使用递归的原因是因为-Exclude值首先应用于-Path值的叶子。 If any of those exclusions match your target directory, then it will be excluded and prevent any of its items from being displayed.如果这些排除中的任何一个与您的目标目录匹配,那么它将被排除并阻止显示其任何项目。 See below:见下文:

$path = 'c:\temp'
# produces nothing because t* matches temp
Get-ChildItem -Path $path -Exclude 't*'

you are doing exclusion parameter correctly in your gci example, but where it may fail in your console silently is processing the results into write-host as it doesn't process the { .. } script block as a foreach-object would do for the individual items.您在gci示例中正确地执行了排除参数,但是在您的控制台中可能会以静默方式失败的地方正在将结果处理到write-host因为它不会像foreach-object那样处理{ .. }脚本块个别项目。 The silent error should be:静默错误应该是:

Write-Host: The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. Write-Host:输入对象不能绑定到命令的任何参数,因为该命令不接受管道输入,或者输入及其属性与接受管道输入的任何参数都不匹配。

With this respect, the correct short foreach-object pipeline notation would be:在这方面,正确的短foreach-object管道符号是:

$excluded = @('*.mkv','*.mp4','*.srt','*.sub','*.ps1')
Get-ChildItem -Exclude $excluded | % { Write-Host $_.FullName }

Regarding the silent errors, I assume your session is set to be Silent , which you can check with the $ErrorActionPreference variable.关于静默错误,我假设您的会话设置为Silent ,您可以使用$ErrorActionPreference变量进行检查。 If you wish to see all errors - in a non-blocking mode, you can set this to Continue eg:如果您希望查看所有错误 - 在非阻塞模式下,您可以将其设置为Continue例如:

$ErrorActionPreference='Continue'

Relevant PS7 pages and examples: PS7相关页面及示例:

Get-ChildItem -Exclude $excluded | Write-Host { $_.FullName } Get-ChildItem -Exclude $excluded | Write-Host { $_.FullName } shouldn't fail silently unless all children in your directory are excluded by your filter.除非您的目录中的所有子项都被过滤器排除,否则Get-ChildItem -Exclude $excluded | Write-Host { $_.FullName }不应静默失败。

If you try to run Get-ChildItem | Write-Host { $_.FullName }如果您尝试运行Get-ChildItem | Write-Host { $_.FullName } Get-ChildItem | Write-Host { $_.FullName } in a non empty directory, it should a throw an error similar to this one: Get-ChildItem | Write-Host { $_.FullName }在一个非空目录中,它应该抛出一个类似于这个的错误:

Write-Host: The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

The reason is that Write-Host can't take an array as parameter (and we know that's an array by doing (Get-ChildItem).GetType() ).原因是Write-Host不能将数组作为参数(我们通过执行(Get-ChildItem).GetType()知道这是一个数组)。

Therefore, you need to first iterate over the elements of the array using ForEach-Object or one of its aliases: foreach or % .因此,您需要首先使用ForEach-Object或其别名之一迭代数组的元素: foreach%

$excluded = @('*.mkv','*.mp4','*.srt','*.sub','*.ps1')
Get-ChildItem -Exclude $excluded | ForEach-Object { Write-Host $_.FullName }
Get-ChildItem -Exclude $excluded | foreach { Write-Host $_.FullName }
Get-ChildItem -Exclude $excluded | % { Write-Host $_.FullName }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM