Comment supprimer des sous-dossiers vides avec PowerShell?
j'ai une part qui est un "tiroir poubelle" pour les utilisateurs finaux. Ils sont capables de créer des dossiers et des sous-dossiers comme ils le souhaitent. J'ai besoin d'implémenter un script pour supprimer les fichiers de plus de 31 jours.
j'ai commencé avec Powershell. Je dois suivre le script de suppression de fichier en supprimant les sous-dossiers qui sont maintenant vides. En raison de l'imbrication de sous-dossiers, je dois éviter de supprimer un sous-dossier qui est vide de fichiers, mais a un sous-dossier sous elle qui contient un fichier.
Par exemple:
FILE3a
a 10 jours. <!-Il a 45 jours.- je veux nettoyer la structure en supprimant les fichiers de plus de 30 jours, et supprimer les sous-dossiers vides.
C:Junksubfolder1asubfolder2aFILE3a
C:Junksubfolder1asubfolder2asubfolder3a
C:Junksubfolder1asubfolder2BFILE3b
résultat Souhaité:
- Supprimer:
FILE3b
,subfolder2B
&subfolder3a
. - Quitter:
subfolder1a
,subfolder2a
etFILE3a
.
je peux nettoyer recursivement les fichiers. Comment puis-je nettoyer les sous-dossiers sans supprimer <!--6? (Le dossier "Junk" restera toujours.)
7 réponses
je voudrais faire en deux étapes - supprimer les anciens fichiers en premier et ensuite le vide dirs:
Get-ChildItem -recurse | Where {!$_.PSIsContainer -and `
$_.LastWriteTime -lt (get-date).AddDays(-31)} | Remove-Item -whatif
Get-ChildItem -recurse | Where {$_.PSIsContainer -and `
@(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -recurse -whatif
ce type d'opération met en évidence la puissance des pipelines imbriqués dans PowerShell, ce qui est démontré par la seconde série de commandes. Il utilise un pipeline imbriqué pour déterminer de façon récursive si un répertoire a zéro fichiers sous lui.
Dans l'esprit de la première réponse, ici, c'est le chemin le plus court pour supprimer les répertoires vides:
ls -recurse | where {!@(ls -force $_.fullname)} | rm -whatif
L'indicateur de force est nécessaire pour les cas où les répertoires ont des dossiers cachés, comme .svn
cela va trier les sous-répertoires avant les répertoires parents travaillant autour du problème de répertoire imbriqué vide.
dir -Directory -Recurse |
%{ $_.FullName} |
sort -Descending |
where { !@(ls -force $_) } |
rm -WhatIf
ajouter au dernier:
while (Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Test-Path) {
Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Remove-Item
}
cela le rendra complet où il continuera à chercher Pour supprimer tous les dossiers vides sous le point $StartingPoint
j'avais besoin de quelques fonctionnalités conviviales pour l'entreprise. Voici mon point de vue.
j'ai commencé avec le code d'autres réponses, puis j'ai ajouté un fichier JSON avec la liste originale des dossiers (y compris le nombre de dossiers par dossier). Supprimé les répertoires vides et enregistrer les.
https://gist.github.com/yzorg/e92c5eb60e97b1d6381b
param (
[switch]$Clear
)
# if you want to reload a previous file list
#$stat = ConvertFrom-Json (gc dir-cleanup-filecount-by-directory.json -join "`n")
if ($Clear) {
$stat = @()
} elseif ($stat.Count -ne 0 -and (-not "$($stat[0].DirPath)".StartsWith($PWD.ProviderPath))) {
Write-Warning "Path changed, clearing cached file list."
Read-Host -Prompt 'Press -Enter-'
$stat = @()
}
$lineCount = 0
if ($stat.Count -eq 0) {
$stat = gci -Recurse -Directory | %{ # -Exclude 'Visual Studio 2013' # test in 'Documents' folder
if (++$lineCount % 100 -eq 0) { Write-Warning "file count $lineCount" }
New-Object psobject -Property @{
DirPath=$_.FullName;
DirPathLength=$_.FullName.Length;
FileCount=($_ | gci -Force -File).Count;
DirCount=($_ | gci -Force -Directory).Count
}
}
$stat | ConvertTo-Json | Out-File dir-cleanup-filecount-by-directory.json -Verbose
}
$delelteListTxt = 'dir-cleanup-emptydirs-{0}-{1}.txt' -f ((date -f s) -replace '[-:]','' -replace 'T','_'),$env:USERNAME
$stat |
? FileCount -eq 0 |
sort -property @{Expression="DirPathLength";Descending=$true}, @{Expression="DirPath";Descending=$false} |
select -ExpandProperty DirPath | #-First 10 |
?{ @(gci $_ -Force).Count -eq 0 } | %{
Remove-Item $_ -Verbose # -WhatIf # uncomment to see the first pass of folders to be cleaned**
$_ | Out-File -Append -Encoding utf8 $delelteListTxt
sleep 0.1
}
# ** - The list you'll see from -WhatIf isn't a complete list because parent folders
# might also qualify after the first level is cleaned. The -WhatIf list will
# show correct breath, which is what I want to see before running the command.