8

我有一个包含大量子目录和文件的目录。我需要删除除 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时,它会删除每个文件,并且似乎忽略了我的过滤器。

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

编辑:我已经包含了一个包含上述示例文件夹结构的 zip 文件。如果您想测试解决方案,请在此处尝试。我还包含了第二个具有所需输出的 ​​zip 文件,因此您可以检查它是否正常工作。

4

6 回答 6

9
(Get-ChildItem c:\folder1\ -recurse | select -ExpandProperty fullname) -notlike 'c:\folder1\subfolder1*' | sort length -descending | remove-item
于 2013-03-06T13:56:12.177 回答
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>

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

于 2013-03-06T14:59:32.587 回答
1

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

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

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

于 2014-03-25T11:48:57.113 回答
0

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

get-childitem -Recurse | where fullname -notlike *SubFolder1* | remove-item -recurse
于 2013-03-06T12:07:40.590 回答
0

只需将通配符放在排除它的位置:

删除项目 * -排除 Folder1\Subfolder1\

于 2013-03-06T12:09:00.377 回答
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
于 2017-07-19T12:30:33.080 回答