Powershell Befehl Fortgeschritten?
Wie würde man ein Skript schreiben, dass doppelte Dateinamen erkennt. Wenn eine Datei KEINEN doppelgänger quasi hat, soll die Datei gelöscht werden. Das muss mit über 500 darein passieren.
wie geht man vor?
2 Antworten
Moin,
doppelte Dateinamen hast du nur, wenn du die Extensions nicht mitzählst. Deshalb ist da etwas die Frage, wie das gemeint ist.
Powershell script to find duplicate elements in the array. (microsoft.com)
Hierrüber kannst du unique Elemente aus einem Array beziehen.
Umgebaut sähe das so aus:
$a=@(1,2,3,1,2)
$b=$a | select –unique
foreach ($c in $b)
{
Write-Host $c.ToString();
}
Und so ähnlich würde ich das auch machen. Ich würde lediglich vorher alle Namen aus dem Ordner ziehen. Die Ausgabe wäre 1, 2 und 3. Dann müsste man nur durch c iterieren und die Dateien löschen.
Übrig bleiben die Duplikate.
LG
$path = "C:\Path"
Set-Location -Path $path
$items=Get-ChildItem $path
$list = New-Object Collections.Generic.List[String]
foreach ($item in $items)
{
$list.Add([System.IO.Path]::GetFileNameWithoutExtension($item));
}
$tbdPS=$list | Group-Object -NoElement
$tbd = New-Object Collections.Generic.List[String]
foreach ($tbdfile in $tbdPS)
{
if ($tbdfile.Count -lt 2)
{
$tbd.Add($tbdfile.Name);
}
}
foreach ($tbdfile in $tbd)
{
foreach ($deletedfile in $items)
{
if ([System.IO.Path]::GetFileNameWithoutExtension($deletedfile) -eq $tbdfile)
{
Remove-Item $deletedfile;
}
}
}
Hiermit läuft das.
LG
Irgendwie sagt er bei mir dazu, dass ich nicht autorisiert bin usw...
Mein Ansatz ist: $dateiort=get-childitem "C:\egal"
$datei= $dateiort | select-object -property name
write-host $datei
$position=$dateiort.substring(0,$dateiort.IndexOf("\"))
write-host $position
Als nächstes würde dann eine If -> while ->Else bedingung kommen. Wie man diese richtig aufstellt verstehe ich noch nicht. Hast du da eine Idee ?
$path = "C:\Path" # Der Ordner mit den Bildern
Set-Location -Path $path # Wir setzen den Pfad von PowerShell zum Pfad, damit wir nachher direkt die Dateinamen nutzen können, ohne den vollständigen Pfad anzugeben.
$items=Get-ChildItem $path # Wir beziehen die Items im Ordner
$list = New-Object Collections.Generic.List[String] # Wir erstellen eine leere Liste
foreach ($item in $items) # Für jedes Item im Ordner...
{
$list.Add([System.IO.Path]::GetFileNameWithoutExtension($item)); # ... fügen wir der Liste den Wert ohne Erweiterung hinzu (bild.png > bild) und nutzen dazu die System.IO Library
}
$tbdPS=$list | Group-Object -NoElement # Wir erstellen eine weitere Liste ohne Duplikate, haben aber eine Auflistung, wie oft welches Item in der Liste auftaucht
$tbd = New-Object Collections.Generic.List[String] # Wir erstellen wieder eine leere Liste
foreach ($tbdfile in $tbdPS) # Für jedes Element in der Liste tbdPS (To be deleted PowerShell)...
{
if ($tbdfile.Count -lt 2) # Wenn bei dem Objekt weniger als 2 Einheiten existieren (also kein Duplikat existiert)...
{
$tbd.Add($tbdfile.Name); # ...fügen wir der leeren Liste diese Einheit hinzu.
}
}
foreach ($tbdfile in $tbd) # Mit jedem Element in der neuen Liste der Einheiten ohne Duplikate...
{
foreach ($deletedfile in $items) #... gehen wir wieder durch alle Elemente im Ordner durch.
{
if ([System.IO.Path]::GetFileNameWithoutExtension($deletedfile) -eq $tbdfile) # Wenn ein Element im Ordner gefunden wurde, welches den selben Namen ohne Endung hat (Die Liste mit der Einheiten ohen Duplikate hat keine Endungen)...
{
Remove-Item $deletedfile; # Löschen wir das Element aus dem Ordner
}
}
}
In einem Ordner können keine zwei Dateien mit dem gleichen Namen sein. Das lässt Windows gar nicht zu.
Willst du schauen, ob in einem Ordner die gleichen Dateien, wie in einem anderen Ordner sind?
Sind die Dateinamen weitestgehend gleich, nur dass sie z.B. verschiedene Dateiendungen haben oder so?
Gib mal ein paar Beispiele, dann kann man ein PowerShell Script daraus bauen.
Ja die Endungen sind verschieden. Jede JPG Datei hat eine png Datei mit dem selben Namen. Nun sind da aber ein paar png Dateien die keine passende jpg Datei haben. Die möchte ich gelöscht haben. Wüsstest du da weiter?
Zur Erklärung in der Langform:
Get-ChildItem -File -Filter "*.png" | Where-Object{(Get-ChildItem -File -Filter "$($_.BaseName).jpg") -eq $null} | Remove-Item
Mit Kommentaren:
Get-ChildItem -File -Filter "*.png" | # Alle Dateien im aktuellen Ordner suchen, die mit .png enden
Where-Object{ # mit dem "|" Symbol (pipe) wird das Ergebnis einer Funktion an die nächste Funktion weitergegeben
# Für jede .png-Datei nach einer entsprechenden .jpg-Datei suchen
# Der BaseName ist der Dateiname ohne Endung
# Wenn die Suche erfolglos war (also keine jpg zu der jeweiligen png gefunden wurde)
(Get-ChildItem -File -Filter "$($_.BaseName).jpg") -eq $null
} | Remove-Item # Gib die Datei per Pipe-Befehl an Remove-Item weiter, wodurch die Datei gelöscht wird
Hab das mit den zahlen nicht genau verstanden. Die Dateinamen müssten ja irgendwie immer bis zu dem letzten „.“ überprüft werden also bis zu Endung. Braucht man da nicht LastIndexOf ?