如何在 PowerShell 中刪除空文件夾

有效的目錄管理在 PowerShell 腳本中至關重要,而 Get-ChildItem
Cmdlet 是導航檔案系統的基石。在清理空文件夾的任務中,遍歷文件夾層級變得至關重要。
本文深入探討 Get-ChildItem
與其他 Cmdlet 的實際使用,以系統地識別和刪除指定路徑中的空目錄。通過利用 PowerShell 強大的腳本功能,用戶可以高效地管理目錄,確保文件系統的井然有序。
PowerShell 中的 Get-ChildItem
Cmdlet
Get-ChildItem
Cmdlet 用於檢索指定位置的所有子項(檔案和文件夾)。當需要刪除給定文件夾路徑中的所有空文件夾時,遍歷文件夾層級是必須的。
因此,Get-ChildItem
Cmdlet 將非常有幫助。此 Cmdlet 接受類似 Recurse
和 Directory
的參數以獲取目錄類型的子項並遞歸遍歷文件夾結構。
語法:
Get-ChildItem -Path -Directory -Recurse
還有許多其他可選的參數可供使用。讓我們創建一個如下所示的文件夾結構。
somepath/testA
testB
testD
testE
a.txt
testC
testF
b.txt
testG
testH
目的是刪除 testA
文件夾中的所有空文件夾。因此,以下文件夾應被刪除。
testD
testG
testH
讓我們獲取指定文件夾路徑(somepath/testA
)中的所有子目錄。
$path = "D:\testA"
$fetchedDirList = Get-ChildItem $path -Directory -Recurse
在這段代碼中,我們將變量 $path
設置為目錄路徑 "D:\testA"
,並使用 Get-ChildItem
Cmdlet 配合 -Directory
和 -Recurse
參數以遞歸方式從指定路徑中獲取所有目錄。結果的目錄列表存儲在變量 $fetchedDirList
中,提供了表示 "D:\testA"
及其子目錄中所有目錄的目錄對象集合。
可以使用別名 gci
來替代 Get-ChildItem
。
$fetchedDirList = gci $path -directory -Recurse
從原始代碼過渡到此修訂版本,我們繼續在變量 $fetchedDirList
中捕獲使用 Get-ChildItem
Cmdlet 獲取的目錄對象。然而,在這段更新的代碼中,我們利用別名 gci
而不是完整的 Cmdlet 名稱 Get-ChildItem
。
這種簡寫保持了從指定路徑 $path
遞歸獲取目錄並將其存儲在 $fetchedDirList
中的功能。
讓我們檢查 $fetchedDirList
變量。
$fetchedDirList
輸出:
所有目錄和子目錄已如預期地獲取。
PowerShell 中的 Where-Object
Cmdlet
我們需要從上述結果中過濾出空目錄。Where-Object
Cmdlet 根據對象的屬性過濾集合中的對象。
可以使用 Where
別名代替 Where-Object
命令。我們需要根據每個目錄內的項目數過濾上述目錄列表。
條件如下所示。
where { (gci $_.fullName).count -eq 0 }
當給定的集合中的對象有 0 個子項時,即被視為空目錄。因此,我們應該刪除它。
讓我們將上一步的輸出管道傳遞給 Where
Cmdlet。
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName).count -eq 0 }
在這行代碼中,我們將變量 $emptyDirectoryList
設置為利用 Where
別名從 $fetchedDirList
過濾的目錄結果。過濾條件在腳本塊中定義,檢查每個目錄中的子項數量(使用 gci $_.FullName
獲取)是否等於 0。
這種方法有效地僅識別和捕獲表示空目錄的目錄對象進入 $emptyDirectoryList
。
讓我們打印 $emptyDirectoryList
。
$emptyDirectoryList
輸出:
結果完全正確。我們只得到了兩個名為 testD
和 testH
的空文件夾。
我們可以輕鬆地從 $emptyDirectoryList
集合中刪除每個對象。可以使用 Remove-Item
Cmdlet 刪除項目。
在此之前,我們需要獲取 $emptyDirectoryList
中每個對象的完整路徑。Select-Object
Cmdlet 可以通過其 FullName
屬性來獲取對象。
$finalListToRemove = $emptyDirectoryList | select -ExpandProperty FullName
在這行代碼中,我們通過提取存儲在 $emptyDirectoryList
中目錄的完整路徑來創建一個新的變量 $finalListToRemove
。我們利用 Select-Object
Cmdlet 配合 -ExpandProperty FullName
參數,使我們能夠檢索 $emptyDirectoryList
中每個目錄對象的 FullName
屬性的值。
因此,$finalListToRemove
包含一個空目錄的完整路徑列表,使它們可以準備刪除。
$finalListToRemove
$finalListToRemove
的輸出:
現在我們有了需要刪除的文件夾列表。
從 PowerShell 中的集合刪除項目
可以使用 ForEach-Object
Cmdlet 循環遍歷集合中的項目。在循環內,我們可以使用 Remove-Item
Cmdlet。
$finalListToRemove | ForEach-Object { Remove-Item $_ }
$_
表示集合中的當前項目。這將刪除 testD
和 testH
文件夾。
這裡有一個棘手的部分。當 testH
文件夾被刪除時,testG
目錄也會變成空的。
因此,我們需要稍微修改腳本。我們應該運行上述程序直到剩下的都是非空文件夾。
我們可以使用 do...while
循環來做到這一點。
$path = "D:\testA"
do {
$fetchedDirList = Get-ChildItem $path -Directory -Recurse
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName).count -eq 0 }
$finalListToRemove = $emptyDirectoryList | select -ExpandProperty FullName
$finalListToRemove | ForEach-Object { Remove-Item $_ }
} while ( $finalListToRemove.count -gt 0 )
在這段代碼中,我們設置了一個循環,系統地檢測並刪除指定路徑及其子目錄下的空目錄。在循環內,我們首先使用 Get-ChildItem
Cmdlet 從指定路徑遞歸獲取所有目錄。
然後,使用 Where-Object
Cmdlet 過濾出空目錄。在提取這些空目錄的完整路徑後,我們使用 Remove-Item
Cmdlet 在 ForEach-Object
循環內逐個刪除它們。
這個循環在還有空目錄可供刪除的情況下運行,確保在指定路徑及其子目錄內徹底清理空目錄。
當您需要考慮隱藏的檔案和文件夾時,可以將 -Force
參數傳遞給 Get-ChildItem
Cmdlet,如下所示。
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName -Force).count -eq 0 }
輸出:
結論
在 PowerShell 中,有效地識別和刪除空文件夾對維持組織良好的文件系統至關重要。通過戰略性地利用如 Get-ChildItem
、Where-Object
和 Remove-Item
等 Cmdlet,用戶可以簡化目錄管理任務。
這些 Cmdlet 使在指定路徑內徹底清理目錄成為可能,提升系統效率和組織架構。通過利用 PowerShell 的腳本環境,用戶可以自動化目錄管理過程,節省時間和精力,同時確保文件系統無雜亂。
憑藉 PowerShell 強大的能力,目錄管理成為系統管理的一個無縫方面,使用戶能夠維護最佳系統性能。
Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.