Powershell - Finden Sie heraus, ob zwei Dateien mit demselben Namen vorhanden sind
-
21-12-2019 - |
Frage
Ich versuche, eine Reihe von Verzeichnissen und Unterverzeichnissen zu überprüfen, um festzustellen, ob sich zwei oder mehr Dateien mit demselben Namen im selben Ordner befinden.Ich denke, mein Problem ist, wie ich versuche, eine Zeichenfolge zu validieren.
Für das folgende Testverzeichnis:
- |-- C: est\
- |--C: est\YY\
- |--C: est\YY\xx.log
- |--C: est\YY\xx.txt
- |-- C: est\ZZ\
- |-- C: est\ZZ .log
- |-- C: est\ZZ .txt
- |--C: est\YY\
Ich brauche meinen Code, um xx.log und ZZ zu finden.log.Ich kann einen Scheck gegen einschließen $_.PSisContainer
(aber ich hielt es nicht für notwendig).
ForEach ($item in (gci "C:\Test\*" -recurse)) {
If ($item.extension -notmatch "txt" -AND $item.basename+".txt" -eq $True) {
Write-Host $item.fullname
}
}
$item.basename+".txt"
stellt die richtige Zeichenfolge bereit, aber ich kann diese Zeichenfolge nicht verwenden, um die Existenz der Datei zu überprüfen.
Kann mir jemand helfen, meinen Code zu korrigieren?Ich würde gerne lernen, wie man mit verketteten Zeichenfolgen wie diesen umgeht - es ist ein Trick, den ich für nützlich halte in anderen Bereichen.
Lösung
Dies ist nicht als Antwort gedacht, sondern als Kommentar, aber es erlaubt mir im Moment nicht, Kommentare hinzuzufügen :(
R_C_III - Ich denke, es gibt zwei Fehler im ursprünglichen Code.
Erstens wird nicht der vollständige Dateipfad erstellt (dh.Verzeichnisname + Basisname + .TEXT).Anstatt Zeichenfolgen zu verketten, hat Keith die Fähigkeit von PowerShell genutzt, Wertersetzungen in Zeichenfolgen mit doppelten Anführungszeichen durchzuführen.beispielsweise.
$s = "there"
write-host "hello $s"
ergebnisse in
hello there
Um Objekteigenschaften auf diese Weise in eine Zeichenfolge einzufügen, müssen Unterausdrücke verwendet werden, wie Keith erklärt.
$file = get-item "c:\somefile.txt"
write-host "$($file.DirectoryName)\$($file.BaseName).NEW"
ergebnisse in
c:\somefile.NEW
Zweitens (gemäß meinem Kommentar zu Keiths Antwort) prüft der ursprüngliche Code nicht auf die Existenz des '.txt' Version der Datei.Die zweite Klausel in der IF-Anweisung versucht, den geänderten Dateinamen mit $True ($item.Basisname+".txt" -eq $ Wahr).Diese Klausel wird immer als falsch ausgewertet.
Keiths Modifikation fügt das CmdLet 'Test-Path' hinzu, das in diesem Fall auf das Vorhandensein des Befehls 'Test-Path' prüft.txt-Datei.
Andere Tipps
Versuchen Sie dies:
gci C:\Test -recurse -file | Where {$_.extension -ne ".txt" -AND (Test-Path "$($_.DirectoryName)\$($_.BaseName).txt")}
Sie brauchen die Initiale nicht Foreach
anweisung als PowerShell-Befehle, die Ausgabedaten direkt am Anfang einer Pipeline verwenden können.Dann filtern Sie Pipeline-Objekte mit dem Where
Befehl.