Powershell的获取子项排除在当前目录中不起作用

问题描述

正如我所提到的,这似乎是Powershell引擎中的错误

当我尝试通过排除某些文件类型(扩展名)来打印当前目录(也存在所述powershell脚本)中的文件时,它不打印任何内容。例如。下面的代码在Powershell控制台中显示“当前文件夹”的内容

gci
gci -pa .

以上两种代码均按如下方式打印目录内容

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

但是当我运行以下代码时,它什么也不会打印,什么时候它必须打印file1.txt:

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

任何人都可以协助弄清为什么会发生以及如何获得我所说的吗?

解决方法

-ExcludeGet-ChildItem一起使用并不直观。要获得与Get-ChildItem一致的结果,您必须使用\*限定路径或使用-Recurse开关。如果您不希望递归,则可以将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

应该使用递归的原因是因为-Exclude值首先应用于-Path值的叶。如果这些排除项中的任何一个与您的目标目录匹配,那么它将被排除并阻止其任何项目显示。见下文:

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

您在gci示例中正确地执行了排除参数,但是在控制台中可能会失败的地方是无提示地将结果处理到write-host中,因为它不处理{ .. }脚本像foreach-object一样对单个项目进行屏蔽。静默错误应为:

写主机:输入对象不能绑定到任何参数 命令,因为该命令不接受管道输入,或者 输入及其属性与采用的任何参数都不匹配 管道输入。

从这方面来说,正确的短foreach-object管道符号应为:

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

关于无提示错误,我假设您的会话设置为Silent,您可以使用$ErrorActionPreference变量进行检查。如果您希望查看所有错误-在非阻止模式下,可以将其设置为Continue,例如:

$ErrorActionPreference='Continue'

相关PS7页面和示例:

,

Get-ChildItem -Exclude $excluded | Write-Host { $_.FullName }不应默默地失败,除非您的目录中的所有子项都被过滤器排除。

如果您尝试在非空目录中运行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.

原因是Write-Host不能将数组作为参数(而我们知道通过执行(Get-ChildItem).GetType()就是数组)。

因此,您需要首先使用ForEach-Object或其别名之一foreach%遍历数组的元素。

$excluded = @('*.mkv','*.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 }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...