0

@Shay Levy の助けを借りて、次のようなスクリプトがあります。

param (
[parameter (mandatory=$true,position=0)]
[string]$Path
)
Get-ChildItem $Path -Recurse -Force | 
Where-Object {$_.PSIsContainer -and (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0} | Remove-Item

パスをパラメーターとして受け入れます-すべてのディレクトリを再帰的に検索します-空のフォルダー(下に子項目がない)の場合、削除されます。それはうまくいきますが、私はそれを完璧にしたいと思っています。

特別な状況を説明する例: 次のようなフォルダー構造のフォルダーがあります:folder/subfolder1.1/subfolder2.1/subfolder3.1.すべてのサブフォルダーは、その親の下にある唯一の子アイテムです。「フォルダー」というディレクトリがあり、サブフォルダー「subfolder1.1」が1つだけ含まれ、ファイルは含まれていません。「Subfolder1.1」には、サブフォルダー「subfolder2.1」が 1 つだけ含まれており、ファイルは含まれていません。「subfolder2.1」には「subfolder3.1」が含まれ、ファイルはありません。このスクリプトを実行した後、実際に削除されるのは「subfolder3.1」です。これは理にかなっています。

「subfolder3.1」が削除された後、その親フォルダー「subfolder2.1」は空のフォルダーになり、削除できます。しかし、スクリプトはその時点を過ぎているため、もう一度スクリプトを実行するまで「subfolder2.1」を削除することはできません。

完璧なスクリプトは、まず「subfolder3.1」を削除し、次にその親フォルダーをチェックして、「ああ、その親サブフォルダー2.1も空です。親フォルダーsubfolder2.1を削除しましょう」を見つけます。subfolder2.1 を削除した後、その親を確認すると、「ああ、subfolder1.1 は空になったので、削除しましょう」とわかります。最終的に、すべてのサブフォルダーが削除された後、この構造「フォルダー」の最上位レベルは空であるため削除されます。

スクリプトに「並べ替え - 降順」を追加しましたが、何もしないようです。

param (
[parameter (mandatory=$true,position=0)]
[string]$Path
)
Get-ChildItem $Path -Recurse -Force | 
Where-Object {$_.PSIsContainer -and (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0} | 
Sort -descending |Remove-Item

「ソート」コマンドを追加するロジックは次のとおりです。上記のフォルダー構造は、次の順序でパイプされます。

folder
folder/subfolder1.1
folder/subfolder1.1/subfolder2.1
folder/subfolder1.1/subfolder2.1/subfolder3.1

上記の順番で、「フォルダ/サブフォルダ1.1/サブフォルダ2.1/サブフォルダ3.1」を削除した後、2.1と1.1とフォルダはスクリプトがポイントを通過したため削除できません。したがって、このフォルダー構造が次の順序でパイプされることを期待して、スクリプトに「並べ替え-降順」を入れていました。

folder/subfolder1.1/subfolder2.1/subfolder3.1
folder/subfolder1.1/subfolder2.1
folder/subfolder1.1
folder

私の希望は、最初に 3.1 を削除してから、3.1 が削除された後に 2.1 が空になるため、2.1 を削除できることです。等々。この夢は美しいですが、うまくいきません。

================================== Update1:

2013 年 4 月 25 日: @mjolinor 助けてくれてありがとう。すぐに実行すると、次のようなエラーが発生します。

...............

+ Foreach {
+        ~
Missing opening '(' after keyword 'foreach'.

...............

最初の foreach ループで次の行を変更して修正しました。

...............

Foreach ($dir in $dirs) {

...............

これで、上記のエラーはなくなり、さらに一歩前進しました。実行できると、フォルダーを反復していることがわかりますが、別のエラーが発生しました。

...............

Index operation failed; the array index evaluated to null.
At C:\Documents\ManualScripts\Cleanup-no-file-and-subdir-dir-rev02.ps1:11 char:13
+             $dirs[$_] = (Get-ChildItem $_ -Force | Measure-Object).Count
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

...............

それに取り組んでおり、あなたと共有します。

============================= アップデート2:

2013 年 4 月 25 日

上記のエラーの理由は次の行です: ...........

Foreach ($dir in $dirs) {

…………

それを次のように変更します: ...........

Foreach ($dir in $_) {

…………

エラーがなくなりました。コンソールを下にスクロールすると、ディレクトリのリストが表示されます。しかし、テストフォルダーがまだ「昇順」で表示されているため、「並べ替え」が期待どおりに機能しなかったようです。抜粋は次のとおりです。

…………

H:\archive\folder\Sub1
H:\archive\folder\Sub1\Sub2.1
H:\archive\folder\Sub1\Sub2.1\Sub3.1

…………

「folder\Sub1\Sub2.1\Sub3.1」は、作成したテスト フォルダー構造です。

=================================== アップデート3

2013 年 4 月 26 日。

それは今動作します!

...................................................

param (
[parameter (mandatory = $True, position = 0)]
[string]$Path
)
$dirs = @{}

Get-ChildItem $Path -Recurse -Force |
Where-Object {$_.PSIsContainer} |
Select -ExpandProperty FullName |
Foreach {
            $dirs[$_] = (Get-ChildItem $_ -Force | Measure-Object).Count
        }
$dirs.keys | Sort Length -Descending # This line is only for displaying output to mornitor sorting is all right
$dirs.keys | Sort Length -Descending  |
Foreach {
         If ($dirs[$_] -eq 0)
          {
           Remove-item $_
           $dirs[($_ | Split-Path -Parent)]--
           }
        }

...................................................

ありがとう@mjolinor。私はハッシュテーブルが好きです:)

4

1 に答える 1

1

テストされていませんが、これでうまくいくと思います:

param (
[parameter (mandatory=$true,position=0)]
[string]$Path
)
$dirs = @{}

Get-ChildItem $Path -Recurse -Force | 
Where-Object {$_.PSIsContainer} |
select -ExpandProperty FullName
foreach {
         $dirs[$_] = (Get-ChildItem $_ -Force | Measure-Object).Count 
         }

$dirs.keys | Sort length -descending |
foreach {
          if ($dirs[$_] -eq 0)
            {
             Remove-Item $_
             $dirs[($_ | Split-Path -Parent)]--
             }
        }
于 2013-04-24T01:33:32.173 に答える