2

正如我在问题中提到的,这似乎是 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 }

谁能帮助弄清楚为什么会发生以及如何获得我提到的内容?

4

3 回答 3

2

-Excludewith的使用Get-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*'
于 2020-09-23T05:10:38.757 回答
1

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

Write-Host:输入对象不能绑定到命令的任何参数,因为命令不接受管道输入,或者输入及其属性与任何接受管道输入的参数都不匹配。

在这方面,正确的短foreach-object流水线表示法是:

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

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

$ErrorActionPreference='Continue'

相关 PS7 页面和示例:

于 2020-09-22T23:57:41.090 回答
1

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','*.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 }
于 2020-09-23T00:26:59.280 回答