如何使用Get-ChildItem -exclude排除多个文件夹?

pet*_*cis 41 directory powershell list

我需要为我们的Pro/Engineer CAD系统生成配置文件.我需要一个来自我们服务器上特定驱动器的文件夹的递归列表.但是我需要在其中排除任何带有"ARCHIVE"的文件夹,包括各种不同的情况.

我写了以下哪些有效但除了它不排除文件夹!!

$folder = "T:\Drawings\Design\*"
$raw_txt = "T:\Design Projects\Design_Admin\PowerShell\raw.txt"
$search_pro = "T:\Design Projects\Design_Admin\PowerShell\search.pro"
$archive = *archive*,*Archive*,*ARCHIVE*

Get-ChildItem -Path $folder -Exclude $archive -Recurse  | where {$_.Attributes -match 'Directory'}  | ForEach-Object {$_.FullName} > $search_pro   
Run Code Online (Sandbox Code Playgroud)

CB.*_*CB. 35

我这样做:

Get-ChildItem -Path $folder -r  | 
          ? { $_.PsIsContainer -and $_.FullName -notmatch 'archive' }
Run Code Online (Sandbox Code Playgroud)

  • 也许这是一个错误.似乎选项'-Exclude'仅适用于文件夹或文件,而不适用于路径. (7认同)

Ver*_*Ray 32

如果这个答案看起来像以前的答案重复,我道歉.我只是想展示一个更新的(通过POSH 5.0测试)解决这个问题的方法.之前的答案是3.0之前的,并不像现代解决方案那样有效.

文档不清楚这一点,但Get-ChildItem -Recurse -Exclude只匹配leaf(Split-Path $_.FullName -Leaf)上的排除,而不是父路径(Split-Path $_.FullName -Parent).匹配排除将只删除具有匹配叶子的项目; Get-ChildItem仍然会进入那片叶子.

在POSH 1.0或2.0中

Get-ChildItem -Path $folder -Recurse  | 
          ? { $_.PsIsContainer -and $_.FullName -inotmatch 'archive' }
Run Code Online (Sandbox Code Playgroud)

注意: @CB一样的答案.

在POSH 3.0+

Get-ChildItem -Path $folder -Directory -Recurse  | 
          ? { $_.FullName -inotmatch 'archive' }
Run Code Online (Sandbox Code Playgroud)

注意: 更新了@CB的答案.

多个排除

这专门针对目录,同时使用Exclude参数排除叶子,并且父类具有ilike(不区分大小写的)比较:

#Requires -Version 3.0
[string[]]$Paths = @('C:\Temp', 'D:\Temp')
[string[]]$Excludes = @('*archive*', '*Archive*', '*ARCHIVE*', '*archival*')

$files = Get-ChildItem $Paths -Directory -Recurse -Exclude $Excludes | %{ 
    $allowed = $true
    foreach ($exclude in $Excludes) { 
        if ((Split-Path $_.FullName -Parent) -ilike $exclude) { 
            $allowed = $false
            break
        }
    }
    if ($allowed) {
        $_
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您希望$Excludes区分大小写,则有两个步骤:

  1. Exclude从中删除参数Get-ChildItem.
  2. 将第一个if条件更改为:
    • if ($_.FullName -clike $exclude) {

注意:此代码具有我永远不会在生产中实现的冗余.您应该简化这一点以满足您的确切需求.它可以作为一个冗长的例子.

  • 值得一个upvote作为解释正在发生的事情的唯一答案:Exclude仅在路径的叶级(即路径中的最后一个文件名或目录名)上运行,而不是作为整体在路径上运行. (4认同)
  • 我不知道为什么我被否决了。也许是因为第一部分与@CB 的答案相同?[我试图编辑他的答案](https://stackoverflow.com/review/suggested-edits/11627206),但编辑被拒绝,原因如下:“此编辑旨在解决帖子的作者和作为编辑没有任何意义。它应该被写成评论或答案。” (2认同)

gui*_*lem 25

跳过某些文件夹的我的KISS方法是链接Get-ChildItem呼叫.这将排除根级文件夹,但不包括更深层次的文件夹(如果这是您想要的).

Get-ChildItem -Exclude folder1,folder2 | Get-ChildItem -Recurse | ...
Run Code Online (Sandbox Code Playgroud)
  • 开始排除您不想要的文件夹
  • 然后排除不需要的文件夹的递归搜索.

我喜欢这种方法,它简单易记.如果您不想在第一次搜索中混合文件夹和文件,则需要使用过滤器.

  • @Silex 好点 `-Filter` 不适用于这种方法 (3认同)
  • 如果您在第二个“Get-ChildItem”上添加“-Filter”,它将不会过滤第一个“Get-ChildItem”调用的根目录中的文件,并且最终会出现意外的文件 (2认同)

alr*_*roc 14

排除模式应该不区分大小写,因此您不必为排除指定每个案例.

也就是说,-Exclude参数接受一个字符串数组,因此只要你这样定义$archive,就应该设置它.

$archive = ("*archive*","*Archive*","*ARCHIVE*");

你也应该删除尾随的星号$folder- 因为你指定-recurse,你应该只需要提供顶级文件夹.

$folder = "T:\Drawings\Design\"

完全修改的脚本.这也会改变您检测是否找到目录的方式,并跳过该目录,Foreach-Object因为您可以直接提取属性并将其全部转储到文件中.

$folder = "T:\Drawings\Design\";
$raw_txt = "T:\Design Projects\Design_Admin\PowerShell\raw.txt";
$search_pro = "T:\Design Projects\Design_Admin\PowerShell\search.pro";
$archive = ("*archive*","*Archive*","*ARCHIVE*");

Get-ChildItem -Path $folder -Exclude $archive -Recurse  | where {$_.PSIsContainer}  | select-Object -expandproperty FullName |out-file $search_pro 
Run Code Online (Sandbox Code Playgroud)

  • [**` - exclude`仅适用于项目的名称**](http://superuser.com/a/663229/180163)所以这将*不起作用.正如在接受的答案中所建议的那样,你需要将结果传递给`Where`(别名`?`)以便过滤`FullName`.@alroc--这可能是获得[纪律严明](http://stackoverflow.com/help/badges/37/disciplined)徽章的好日子. (10认同)
  • 终于解决了!`Get-ChildItem -Path $ folder -Recurse | ?{$ _.psiscontainer -and $ _.fullname -notmatch'archive'} | select-Object -expandproperty FullName | out-file $ search_pro`这似乎有效谢谢你的帮助@alroc&@CB (3认同)
  • `$ archive =("*archive*","*Archive*","*ARCHIVE*")`和`$ archive ="*archive*","*Archive*","*ARCHIVE*"`和`$ archive = @("*archive*","*Archive*","*ARCHIVE*")`是等效的. (2认同)

js2*_*010 6

您可以像这样排除正则表达式“或”符号,假设您想要的文件与您要排除的文件夹不具有相同的名称。

$exclude = 'dir1|dir2|dir3'
ls -r | where { $_.fullname -notmatch $exclude }

ls -r -dir | where fullname -notmatch 'dir1|dir2|dir3'
Run Code Online (Sandbox Code Playgroud)


小智 5

我知道这已经很老了-但是在寻找一个简单的解决方案时,我偶然发现了这个线程...如果我的问题正确,那么您正在寻找一种使用Get-ChildItem列出多个目录的方法。使用Powershell 5.0似乎有一种更简单的方法-示例

Get-ChildItem -Path D:\ -Directory -Name -Exclude tmp,music
   chaos
   docs
   downloads
   games
   pics
   videos
Run Code Online (Sandbox Code Playgroud)

如果没有-Exclude子句,则tmp和音乐仍将在该列表中。如果不使用-Name,则由于Get-ChildItem的详细输出,-Exclude子句将不起作用。希望这对某些正在寻找一种简单方法列出所有目录名称而不列出某些目录名称的人有所帮助...

欢呼声


小智 5

我就是这样做的:

Get-ChildItem -Recurse -Name | ? {$_ -notmatch 'node_modules' }
Run Code Online (Sandbox Code Playgroud)

这会递归地列出每个文件的完整路径,其路径中不包含node_modules。显然,您应该使用要过滤的任何字符串更改 node_modules