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 ファイルを含めました。ソリューションをテストしたい場合は、そこで試してみてください。目的の出力を含む 2 番目の 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

次の 2 つのコマンドを連続して呼び出すことができます。

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

まず、Folder1 以外のすべてを削除します。その後、Subfolder1 を除く Folder1 内のすべてを削除します。このようにして、除外するサブサブフォルダーを指定する必要がなくなります。

于 2014-03-25T11:48:57.113 に答える
0

そのワイルドカードを除外するだけです:

アイテムの削除 * -Folder1\Subfolder1\ を除外

于 2013-03-06T12:09:00.377 に答える
0

理由や正しい方法を提供することはできませんが、回避策を考えました。get-childitem コマンドレットの出力を remove-item コマンドレットにパイプしてみることができます (特にテストされていないため、若干の調整が必要になる場合があります)。

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