Powershell Verzeichnisse vergleichen mit Zwischenschritt
Hi@All,
Ablauf:
1. Verzeichnis A (root: c:\temp\dir1) einlesen (pfad ab root, name, länge, letzte mal geschrieben) --> Ergebnis in txt file
2. Verzeichnis B (root: c:\temp\dir2) einlesen (pfad ab root, name, länge, letzte mal geschrieben) --> Ergebnis in txt file
3. Dateien Vergleichen --> Diff farbig ausgeben + Indicator
Problem:
Wenn ich über gci ein recurse durch das Verzeichnis laufe und das in ein out-file pipe bekomme ich zuviel an Ausgabe in der Datei.
Mit dem Zwischenpipe Block ist es weniger:
Wie bekomme ich es hin das dort statt dem FullName der Pfad und unterverzeichnisse beginnend ab dem dir1 oder dir2 in der Datei landet?
Man könnte mit -replace arbeiten, aber geht das auch eleganter?
Zum CompareObject im Schritt 3 gehts später, wenn die Dateien mit get-Content eingelesen wurden.
Gruß
Ablauf:
1. Verzeichnis A (root: c:\temp\dir1) einlesen (pfad ab root, name, länge, letzte mal geschrieben) --> Ergebnis in txt file
2. Verzeichnis B (root: c:\temp\dir2) einlesen (pfad ab root, name, länge, letzte mal geschrieben) --> Ergebnis in txt file
3. Dateien Vergleichen --> Diff farbig ausgeben + Indicator
Problem:
Wenn ich über gci ein recurse durch das Verzeichnis laufe und das in ein out-file pipe bekomme ich zuviel an Ausgabe in der Datei.
Mit dem Zwischenpipe Block ist es weniger:
gci "<pfad>" -recurse | %{$_.FullName} | Out-File "c:\temp\DIR1.txt"
Wie bekomme ich es hin das dort statt dem FullName der Pfad und unterverzeichnisse beginnend ab dem dir1 oder dir2 in der Datei landet?
Man könnte mit -replace arbeiten, aber geht das auch eleganter?
Zum CompareObject im Schritt 3 gehts später, wenn die Dateien mit get-Content eingelesen wurden.
Gruß
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 319023
Url: https://administrator.de/forum/powershell-verzeichnisse-vergleichen-mit-zwischenschritt-319023.html
Ausgedruckt am: 14.04.2025 um 19:04 Uhr
22 Kommentare
Neuester Kommentar

Hi.
Wieso das Gedöns in Textdateien schreiben ?????
Das geht doch so ohne irgendwelche Zwischenschritte mit compare.
Powershell ist objektorientiert, da ist das Schreiben in eine Textdatei als Zwischenschritt nur kontraproduktiv.
Wenn man einzelne Eigenschaften ausgeben will hilft einem select -Expand <PROPERTY>
Aber wie gesagt für Vergleiche ist das vollkommen überflüssig wenn man schon alle Eigenschaften der Objekte in Variablen hat.
Gruß
p.s. Robocopy mit Parameter /L macht dir das frei Haus.
Wieso das Gedöns in Textdateien schreiben ?????
Das geht doch so ohne irgendwelche Zwischenschritte mit compare.
Powershell ist objektorientiert, da ist das Schreiben in eine Textdatei als Zwischenschritt nur kontraproduktiv.
Wenn man einzelne Eigenschaften ausgeben will hilft einem select -Expand <PROPERTY>
Aber wie gesagt für Vergleiche ist das vollkommen überflüssig wenn man schon alle Eigenschaften der Objekte in Variablen hat.
Gruß
p.s. Robocopy mit Parameter /L macht dir das frei Haus.

Zitat von @H41mSh1C0R:
Beim Expand bekommst du allerdings z.B. den $_.Name aber wie schauts aus wenn du den Teilpfad haben willst?
Hast du dir überhaupt schon mal alle Eigenschaften auf der Konsole angesehen?Beim Expand bekommst du allerdings z.B. den $_.Name aber wie schauts aus wenn du den Teilpfad haben willst?
Da gibt es alles was du brauchst frei Haus:
- DirectoryName
- Directory.Parent.Name
- Directory.Parent.Fullname
- Basename
- etc.

Ich kann ja blind sein, allerdings ist kein Property dabei was mir den Subpfad liefert beginnend AB der Ebene z.B. dir1.
Wie soll das Script das wissen, also musst du es ihm sagen entweder durch ein Replace oder durch ein Split bei dem du die Anzahl der Backslashes deines vorgegebenen Pfades zählst und damit dann den Pfad der Datei splittest.
Nein. Das Root hast du ja schon in einer Variablen, also ist das nicht nötig.

Achtung, das ist keine gute Idee. Bei dieser Replace-Variante wird Groß und Kleinschreibung unterschieden. Das geht also unter Umständen schief.
Also entweder
oder
Also entweder
%{$_.Fullname.toLower().Replace($cut.toLower(),'')}
%{$_.Fullname -replace "^$([regex]::Escape($cut))",''}
So der nächste Schritt die Größe mit rein und dann geht's an das vergleichen. =)
Würde ich wenn dann nur in eine CSV schreiben.
Logisch weil das dann kein Objekt ist, aber auch zu umständlich...
Get-ChildItem $path -Recurse | Select FullName, Length, @{n="RelativePath";e={$_.FullName.toLower().Replace($cut.toLower(), '')}} | export-csv $ff -delimiter ";" -NoType -Encoding UTF8

Bei Import-CSV fehlt die Angabe des Delimiters!
Also mit dem @.... hängst du somit eine Spalte "RelativePath" an mit gekürztem Pfad. *merk*
Das ist keine Spalte sondern eine "Eigenschaft" und das Verfahren nennt sich Calculated Properties
Ja, wird beim Passthru als Eigenschaft dem Objekt als Member hinzugefügt.
Der wird auch ausgegeben. Alle anderen Eigenschaften sind doch auch Teil des Objektes und beim Debuggen stehen dort auch die Werte drinnen.
Doch wieso gibt er sie nicht mit aus?
Weil du es falsch ausgibst der interpretiert das als zusätzlichen Parameter von write-host und nicht als das auszugebende...Doch wieso gibt er sie nicht mit aus?
Write-Host "$($_.FullName) $($_.SideIndicator)" -ForegroundColor 'red'

Weil du sie nicht wie oben geschrieben angepasst hast
und es immer noch falsch angegeben hast.

Geht hier einwandfrei, du machst also noch irgendwo einen Fehler. Keine Ahnung wo ich habe deine Daten hier nicht...

Ich hab doch oben schon geschrieben das dir die Angabe des Delimiters bei Import-CSV fehlt!
$ff = Import-Csv $firstFile -Delimiter ";"
$sf = Import-Csv $secondfile -Delimiter ";"