2016-08-09 40 views
0

Ich habe an einem PowerShell-Skript gearbeitet, das die Verzeichnisstruktur beim Verschieben verschachtelter Ordner bewahrt. Ich habe ein bisschen Schwierigkeiten, die Rekursionslogik richtig zu bekommen.Rekursionslogik

Dies ist eine grobe, so dass es noch keinen Versuch/Catch Fehlercode gibt. Ich habe die Remove-Item auskommentiert, um versehentliche Läufe zu verhindern.

Die Logik, die ich dafür ausgearbeitet habe, ist wie folgt.

  • prüfen & get Basisstruktur für Unterverzeichnisse
  • Go eine Ebene in und erneut prüfen
  • bis keine Verzeichnisse auf Weiter und dann eine Ebene nach oben zurück.
  • Cab-Verzeichnis, Verzeichnis entfernen, Protokoll für automatisierte Extraktion schreiben (Dateinamen der Unterverzeichnissen).
  • Wiederholen Sie den Vorgang bis nächste Stufe und weiter bis Basisverzeichnis
function Chkfordir ($clevel) 
{ 
    $dir = dir $clevel | ? { $_.PSIsContainer -eq $true } #Does Current Level have Folders? 
    if($dir -ne $null) # Yes 
    { 
     Chkfordir $dir  #Go Deeper 
    } 
    if ($dir -eq $null) #Deepest Branch 
    { 
     return    # Go Back One Level and begin Cabbing 
    } 

    $dir | % { 
     Compress-Directory $_.FullName (".\" + [string]$_.Name + ".cab") 
     echo ($_.FullName + ".cab" >> .\cleaf.log" 
     #Remove-Item -Recurse $_.FullName 
     return 
    } 
} 

Der Funktionsaufruf Compress-Directory von here ist.

bearbeiten Änderungen:

Re-Postleitzahl April (18.08)

bearbeiten 18.8 So hatte ich endlich eine Chance, es zu testen und die Logik scheint jetzt zu funktionieren. Es gab einige Probleme.

Die meisten Schwierigkeiten kamen mit einem Powershell Gotcha und dem unbemerkten Problem, dass Compress-Directory nicht pfadunabhängig ist. Sieht so aus, als müsste ich diese Funktion später schreiben, um Pfad-unabhängig zu sein.

Die Powershell Gotcha war in einer Typänderung für einen Wert für die Pipeline. Nach dem Zurückkehren von einem Funktionsverzeichnis werden Elemente offenbar von System.IO.FileInfo zu System.IO.DirectoryInfo mit unterschiedlich benannten Elementfunktionen geändert.

Echo wurde durch Add-Content ersetzt, da die Umleitungsoperatoren nicht in Powershell funktionieren.

Es gab auch einige unerklärte Zustände zu kämpfen. Ein Blattverzeichnis, das keine Dateien enthält, würde Compress-Directory zu einem Fehler führen oder ohne eine Dateierstellung im Hintergrund ausführen (wodurch die Hierarchie nicht erhalten bleibt).

Die Lösung bestand darin, einen Add-Content für Blattordner vor der Rückgabe hinzuzufügen und Add-Content vor das Compress-Directory zu verschieben, so dass mindestens eine Datei in jedem Verzeichnis vorhanden ist.

Ich habe meine aktuelle Version unten eingefügt, aber es ist ein work in progress.

function Chkfordir ($clevel) 
{ 
    $dir = dir $clevel | ? { $_.PSIsContainer -eq $true } # Get Folders? 
    if ($dir -eq $null) { #Check if deepest branch 
     Add-Content (Join-Path $_.PSPath "\leaf.log") ([string]$_.FullName + ".cab") 
     return $_    # Return one level up and cab 
    } 

    $dir | % { #for each sub go deeper 
     Chkfordir $_.FullName 
     Add-Content (Join-Path $_.PSParentPath "\branch.log") ([string]$_.FullName + ".cab") 
     Compress-Directory $_.FullName ([string]$_.Name + ".cab") 
     #Remove-Item $_.FullName -recurse 
    }   
} 

Antwort

0

Sie müssen für jedes Unterverzeichnis rekursiv und es nach den rekursiven Aufruf kehrt zu komprimieren:

function Chkfordir($clevel) { 
    Get-ChildItem $clevel | 
     Where-Object { $_.PSIsContainer } | 
     ForEach-Object { 
      Chkfordir $_ 
      Compress-Directory ... 
      ... 
     } 
} 

diese Weise werden Sie automatisch zuerst absteigen, dann die Archive erstellen, wie Sie zurück.

+0

Danke, ich hatte nicht bemerkt, dass es nicht jedes Unterverzeichnis und rekursiv von dort nahm. Ich habe den Code aktualisiert und werde ihn später testen, wenn ich etwas Zeit habe. – Lorek