首页 > 解决方案 > 在 PowerShell Get-ChildItem -Exclude 不与 -Recurce 参数一起使用

问题描述

在此处输入图像描述我想递归搜索所有目录,除了以_(下划线)开头的目录。

例如:_archive_DO_NOT_DELETE_processing等。

我使用了下面的代码,但它不起作用。似乎 exclude 不适用于 recurse 。有任何想法吗?

$exclude = @("_*")
$source = "C:\code\Powershell\delete empty folders\New folder\" 
$allitems = Get-ChildItem $source -Directory -Exclude $exclude -Recurse
foreach($myItem in $allitems)
{
  echo $myItem.fullname
} 

输出:

C:\code\Powershell\删除空文件夹\新文件夹\新文件夹\新文件夹
C:\code\Powershell\删除空文件夹\新文件夹\新文件夹\新文件夹\新文件夹
C:\code\Powershell\删除空文件夹\新建文件夹\新建文件夹\新建文件夹 (2)
C:\code\Powershell\删除空文件夹\新建文件夹\新建文件夹\新建文件夹 (3)
C:\code\Powershell\删除空文件夹\新建文件夹\新建文件夹\新建文件夹(3)\新建文件夹
C:\code\Powershell\删除空文件夹\新文件夹\_archive\新文件夹

所以,正如我之前所说,我想避免使用下划线开头的目录,因此最后一行不应该出现。

即使我也使用了下面的代码,仍然是相同的输出:

$exclude = @("_*")
$source = "C:\code\Powershell\delete empty folders\New folder\"
$allitems = Get-ChildItem $source -Recurse -Directory |
            Where {$_.FullName -notlike $exclude}
foreach($myItem in $allitems)
{
    echo $myItem.fullname
}

标签: powershell

解决方案


这里发生的是 Get-ChildItem 的-exclude参数基于项目的 name 属性工作。使用通配符时,名称必须与非通配符部分匹配。当您的目录名称以空格开头时,不会发生这种情况。让我们看一个例子:

# Create two files, one starts with a space, the other doesn't
Set-Content -Path " data1.txt" -Value $null
Set-Content -Path "data2.txt" -Value $null

gci -name "data*"
 data2.txt

gci -name " data*"
 data1.txt

结果是单场比赛,强硬的通配符被使用了。原因是data1.txt' 的第一个字符是空格,并且与参数的第一个字符不匹配,即d.

以狡猾而-exclude臭名昭著。通过管道将结果传递给where-object. 像这样,

Get-ChildItem $source -Directory -recurse | ? {$_.fullname -NotMatch "\\\s*_"} | % { $_.fullname }
# "\\\s*_" is regex for \, any amount of whitespace, _ 
C:\code\Powershell\delete empty folders\New folder\New folder
C:\code\Powershell\delete empty folders\New folder\New folder\New folder
C:\code\Powershell\delete empty folders\New folder\New folder\New folder (2)
C:\code\Powershell\delete empty folders\New folder\New folder\New folder (3)
C:\code\Powershell\delete empty folders\New folder\New folder\New folder\New folder
C:\code\Powershell\delete empty folders\New folder\New folder\New folder (3)\New folder

Get-ChildItem $source -Directory -recurse | ? {$_.fullname -Match "\\\s*_"} | % { $_.fullname }
C:\code\Powershell\delete empty folders\New folder\ _archive
C:\code\Powershell\delete empty folders\New folder\ _archive\New folder

请注意,匹配需要评估FullName属性。仅使用Name将仅匹配叶级别。


推荐阅读