Powershell Befehl Fortgeschritten?

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

Woher ich das weiß:Berufserfahrung – 💻 Zertifizierter Sr. Cloud Engineer im IT-Consulting

Lukmon22 
Fragesteller
 28.10.2021, 10:49

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 ?

0
Dultus, UserMod Light   28.10.2021, 10:50
@Lukmon22

Du kannst einfach eine neue Liste erstellen;

$list.Add([System.IO.Path]::GetFileNameWithoutExtension($var));

Du kannst dann einfach System.IO.Path verwenden, um die Extensions zu entfernen.

0
Dultus, UserMod Light   28.10.2021, 11:11
@Lukmon22
$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

0
Lukmon22 
Fragesteller
 28.10.2021, 11:55
@Dultus, UserMod Light

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 ?

0
Dultus, UserMod Light   28.10.2021, 12:00
@Lukmon22
Irgendwie sagt er bei mir dazu, dass ich nicht autorisiert bin usw...

Schätze mal, du hast die Execution Policy auf Strict?

Set-ExecutionPolicy Unrestricted

Im Adminmode dürfte das schon lösen. Meinen Ansatz habe ich probiert und er funktionierte auch. ^^

0
Lukmon22 
Fragesteller
 28.10.2021, 12:06
@Dultus, UserMod Light

Hab keine berechtigung dazu, arbeite nicht an einem privaten Desktop. Hast du keine Ansätze zu meiner Idee ?

0
Dultus, UserMod Light   28.10.2021, 12:09
@Lukmon22

Hm. Dann habe ich keine Ergänzung - ich würde auch deinen Ansatz so behandeln. Man würde damit einfach die GetFileNameWithoutExtension Methode austauschen.

0
Lukmon22 
Fragesteller
 28.10.2021, 12:57
@Dultus, UserMod Light

Könntest du deinem Skript noch kommentare hinzufügen, was die Funktionen der Zeilen beschreibt ? Ich bin dir sehr dankbar für die Mühe!!!

1
Dultus, UserMod Light   28.10.2021, 13:07
@Lukmon22
$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
            }
        }
}
1
Erzesel  28.10.2021, 19:46
@Dultus, UserMod Light

Hattest du beim schreiben diese Monsters nicht das Gefühl, das es irgendwie etwas von Kanonen auf Spatzen hat?

dir "*.png" | ?{!(Test-Path "$_.BaseName.jpg") } |rm
0
Erzesel  29.10.2021, 10:30
@Dultus, UserMod Light

Ich denke mal, das kommt raus, wenn man ein kompaktes GroupBy in Linq zu Powershell umsetzt. Ginge es nicht um Dateien, welche man so "billig" testen kann , wäre auch in Powershell das Gruppieren und Auswerten der Trefferzahl ein ein guter Ansatz.

1

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.


Lukmon22 
Fragesteller
 28.10.2021, 10:38

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?

0
Dultus, UserMod Light   28.10.2021, 10:40
@Lukmon22

Siehe meine Antwort - einfach gucken, ob die Datei zwei mal vorhanden ist. Wenn nicht, weg damit. Man kann wenn nötig auch auf die Endung prüfen.

0
daCypher  28.10.2021, 11:04
@Lukmon22

Löscht alle png-Dateien im aktuellen Ordner, die keine jpg-Datei mit dem gleichen Namen hat.

dir -file -filter "*.png" | ?{(dir -file -filter "$($_.BaseName).jpg") -eq $null} | rm
1
daCypher  28.10.2021, 13:38
@daCypher

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
1
Erzesel  28.10.2021, 19:40
@daCypher

fast perfekt, kurz und schmerzlos. ...nur das dir zum überprüfen der Nichtexistenz einer einzelnen Datei ist etwas der Overkill😁

dir "*.png" | ?{!(Test-Path "$_.BaseName.jpg") } |rm

Keine Ahnung was das Gewurstel mit den Listen da oben sollte.

1
daCypher  29.10.2021, 07:53
@Erzesel

Ah, ich wusste, dass es auch einen Befehl gibt, mit dem man prüfen kann, ob eine Datei existiert. Hab bloß die Funktion Test-Path nicht gefunden. Wieder was neues gelernt. Danke 👍

1
Lukmon22 
Fragesteller
 29.10.2021, 10:40
@Erzesel

Moin Erzesel, kannst du dir meine neuste Frage anschauen auf meinem profil?

0