1

我想过滤包含特定条件的文件夹列表,同时排除 PowerShell 中的另一组条件。

下面的代码是目前正在玩的部分继承的代码;-Exclude似乎排除*EDS*了名称中包含但不包含的文件夹*eng*。以下是仍然包含的内容的示例输出:

C:\Users\USERNAME\Box\CTRL Active Projects\project1\project1_OPS\06-Software\04-Database Backups\01-Record Backup
C:\Users\USERNAME\Box\CTRL Active Projects\project1\project1_OPS\06-Software\04-Database Backups
C:\Users\USERNAME\Box\CTRL Active Projects\project1\project1_OPS\01-Eng\03-Submittals WIP\Backups

最终-Exclude *eng*, *EDS*可能会转换为变量/命名数组列表。

# Find sub-folder within job folder
$DatabaseFolder = (Get-ChildItem -Path $JobFolder -Filter "*Backup*" -Exclude *eng*, *EDS* -Recurse -Directory).Fullname | Sort-Object -Descending -Property LastWriteTime
Write-Output $DatabaseFolder

$JobFolder返回搜索子目录的路径:

C:\Users\USERNAME\Box\CTRL Active Projects\project1\

其他一些背景信息:PowerShell 5.1 被用作管理员,Windows 10 操作系统

有人可以帮我理解为什么代码仍然包含一些排除的参数吗?

4

2 回答 2

3
  • -Filter-Include/都只-Exclude最后一个路径组件进行操作 - 即输入文件系统项的名称.Name属性)。

  • -Exclude与 结合时,-Recurse仅排除匹配项本身,不排除其子树。也就是说,排除目录的内容(子项)仍会被枚举(除非它们的名称也恰好与排除模式匹配)。

因此,...\01-Eng\03-Submittals WIP\Backups例如,仍然包含在您的输出中:*eng* -Exclude过滤器排除了...\01-Eng自身,但继续枚举其子目录

从 PowerShell (Core) 7.2.1 开始,没有直接的方法可以通过通配符模式从枚举中排除目录子树;GitHub 问题 #15159建议添加此功能。Get-ChildItem -Recurse


因此,您必须通过使用与完整路径(属性)匹配的调用进行过滤来执行排除:Where-Object.FullName

Get-ChildItem -Recurse -Directory -Path $JobFolder -Filter *Backup* |
  Where-Object FullName -notmatch 'eng|EDS'

注意:为简洁起见,使用交替 ( )-notmatch正则表达式|用于匹配多个子字符串。

要使用通配符表达式,您必须多次使用运算-notlike符,每个模式一次(这还需要您使用脚本块参数,显式使用,即您不能使用上面显示的简化语法; 换句话说:) 。$_
Where-Object { $_.FullName -notlike '*eng*' -and $_.FullName -notlike '*EDS*' }

于 2022-02-01T20:23:26.767 回答
0

我在文档中没有看到有关使用过滤器和排除的任何内容:

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.2

但是,由于它没有按您的预期工作,您始终可以手动执行排除:

gci -recurse -directory | ? { $_.Name -notlike "*eng*" -and $_.Name -notlike "*EDS*" }
于 2022-02-01T19:00:34.220 回答