Powershell - 删除除特定子目录中的项目之外的所有项目

时间:2013-03-06 11:50:59

标签: powershell

我有一个包含大量子目录和文件的目录。 我需要删除除SubFolder1下的所有文件。

Initial State:                       Desired Output:

\                                    \
|_Folder1                            |_Folder1
| |_File1.txt                          |_SubFolder1
| |_File2.xml                            |_File3.csv
| |_SubFolder1                           |_File4.exe
| | |_File3.csv
| | |_File4.exe
| |_Subfolder2
|_Folder2
| |_ <more files here>
|_Folder3 (etc)

所以这就是我的尝试:

Remove-Item * -exclude Folder1\Subfolder1\*

我收到这样的警告:

Confirm
The item at C:\foo\Folder1 has children and the -recurse parameter was not specified. 
If you continue, all children will be removed with the item. Are you sure you want to continue?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "Y"):

当我指定-recurse时,它会删除每个文件,并且似乎忽略了我的过滤器。

发生了什么事,以及这样做的正确方法是什么?

编辑: 我已经包含了一个包含example folder structure的zip文件。如果您想测试解决方案,请在那里尝试。我还添加了第二个包含desired output的zip文件,因此您可以检查它是否正常工作。

6 个答案:

答案 0 :(得分:8)

(Get-ChildItem c:\folder1\ -recurse | select -ExpandProperty fullname) -notlike 'c:\folder1\subfolder1*' | sort length -descending | remove-item

答案 1 :(得分:5)

也许有一个更简单的解决方案,但这个功能应该可以解决问题:

function Clean-Folder
{
    param(
        [string]$rootfolder,
        [string[]]$excluded
    )
    $rootfolder = resolve-path $rootfolder
    Push-Location $rootFolder
    if($excluded -notmatch "^\s*$")
    {
        $excluded = Resolve-Path $excluded
    }
    $filesToDel = Get-ChildItem $rootFolder -Recurse
    # Excluding files in the excluded folder
    foreach($exclusion in $excluded)
    {
        $filesToDel = $filesToDel |?{$_.fullname -notlike ("{0}\*" -f $exclusion)}
        # Excluding parent folders of the excluded folder
        while($exclusion -notmatch "^\s*$")
        {
            $filesToDel = $filesToDel |?{$_.fullname -ne $exclusion}
            $exclusion = Split-Path -parent $exclusion
        }
    }
    $filesToDel |Remove-Item -Recurse -ErrorAction SilentlyContinue
    Pop-Location
}

基本上,它所做的是以递归方式列出文件夹中的所有项目,然后删除要保留的项目,子项目及其所有父文件夹。最后,删除剩余的列表。

只需声明上面的函数,然后:

Clean-Folder -rootfolder <path> -excluded <folder you want to exclude>

编辑:使root文件夹接受相对路径,并排除接受文件夹列表

答案 2 :(得分:1)

您可以调用两个连续的命令:

Remove-Item * -recurse -exclude Folder1
Remove-Item Folder1\* -recurse -exclude Subfolder1

首先删除除Folder1之外的所有内容。之后,删除Folder1中除Subfolder1之外的所有内容。这样您就不必指定要排除的子文件夹。

答案 3 :(得分:0)

我无法提供原因或方法,但我确实想到了解决方法。您可以尝试将get-childitem cmdlet的输出传递给remove-item cmdlet(未经过专门测试,因此可能需要稍微调整一下):

get-childitem -Recurse | where fullname -notlike *SubFolder1* | remove-item -recurse

答案 4 :(得分:0)

在排除它的上面放弃那个通配符:

Remove-Item * -exclude Folder1 \ Subfolder1 \

答案 5 :(得分:0)

我遇到了同样的问题,最后我解决了它:

Get-Childitem folder_for_clear_path -Exclude folder_for_exclude_name | Remove-Item -Recurse

编辑: 对于此问题,请使用下一个代码:

Get-Childitem C:\foo -exclude Folder1 | Remove-Item -recurse 
Get-Childitem C:\foo\Folder1 -exclude SubFolder1 | Remove-Item -recurse