使用Powershell的方法Get-Childitem时排除多个子文件夹

nix*_*xda 5 powershell foreach

是)我有的

以下工作代码列出了放置脚本的所有子文件夹中的所有文件.
它仅包含某些文件类型,并排除某个文件夹中的所有文件.到现在为止还挺好

$fileInclude = @("*.txt", "*.hgr", "*.dat")           
$folderExclude = "C:\folder2"    
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition

gci $scriptPath -recurse -include $fileFilter | Where {$_.FullName -notlike "$folderExclude*"} 
Run Code Online (Sandbox Code Playgroud)

我的测试的文件结构如图所示

C:.
?   Myscript.ps1
?
????folder1
?   ?   file1.dat
?   ?   file1.hgr
?   ?   file1.txt
?   ?
?   ????folder3
?           file3.dat
?           file3.hgr
?           file3.txt
?
????folder2
        file3.dat
        file3.hgr
        file3.txt
Run Code Online (Sandbox Code Playgroud)

我想要的是

现在我想替换第二行

$folderExclude = "C:\folder2"
Run Code Online (Sandbox Code Playgroud)

用数组.后来有几十条路径.

$folderExclude = @(
        "C:\folder2", 
        "C:\folder1\folder3"    
        )
Run Code Online (Sandbox Code Playgroud)

显然这不会起作用,因为-notlike需要一个字符串而不是一个字符串数组.

我无法理解如何实现这一点.我想我需要一个for-each循环?

Kei*_*ill 6

你也可以走这条路:

$exclude = @('c:\folder2*', 'c:\folder1\folder3'} 
gci | Where {$fn = $_.Fullname; ($exclude | Where {$fn -like $_}).count -eq 0}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是V4,则可以使用方便的新常用参数-PipelineVariable:

gci -pv fse | Where {($exclude | Where {$fse.FullName -like $_}).count -eq 0}
Run Code Online (Sandbox Code Playgroud)

请注意,这种方法有一个缺陷,如果folder1包含一个名为folder3foobar的文件,该文件将被排除.要解决此问题,您需要将排除项修改为c:\ folder1\folder3*,然后在与fse.FullName进行比较时,如果fse是目录而不是文件,则需要附加反斜杠.

这是另一种基于-match允许左侧数组工作的方法:

 gci | Where {!($exclude -match [regex]::escape($_.Fullname))}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果其中一个目录与$ exclude数组的术语匹配,那么将会有输出并且被强制转换为true但后来被反转!.