functionstrut
Goto Top

(PS) 3 Hashtables zum finden von Ordernamen

Hallo,

Folgende Ausgangssituation:
Ich habe 3 Hastables.

$a = @{
Eins="EINS"
Zwei="ZWEI"
Drei="DREI"}

$b = @{
Blau="BLAU"
Schwarz="SCHWARZ"
Gelb="GELB"}

$c = @{
Haus="HAUS"
Baum="BAUM"
Zaun="ZAUN"}

Powershell soll alle Ordnernamen prüfen ob von JEDER Hastable genau 1 Wert(Key) im Ordnernamen vorhanden ist.

Treffer Wären:
C:\123_Eins_Blau_Haus_123\Datei.txt
C:\123_Drei_Blau_Haus_123\Datei.txt
C:\123_Drei_Gelb_Baum_123\Datei.txt

KEIN Treffer:
C:\123_Eins_Haus_123\Datei.txt
C:\123_Gelb_Zaun_123\Datei.txt

es muss also im Ordnernamen immer aus jeder Hashtable 1 Wert zutreffen und dann die Datei verschoben werden mit der Möglichkeit den Value des "Treffers" für die -Destination zu nutzen.

Ziele in dem Beispiel wären:
C:\123_EINS_BLAU_HAUS_123\Datei.txt
C:\123_DREI_BLAU_HAUS_123\Datei.txt
C:\123_DREI_GELB_BAUM_123\Datei.txt

das wäre so das grobe, den rest könnte ich mir dann selber zurecht basteln. Habt ihr eine Idee?

Content-Key: 391728

Url: https://administrator.de/contentid/391728

Printed on: April 25, 2024 at 11:04 o'clock

Mitglied: 137443
137443 Nov 05, 2018 updated at 15:30:36 (UTC)
Goto Top
$a = @{
Eins="EINS"  
Zwei="ZWEI"  
Drei="DREI"}  

$b = @{
Blau="BLAU"  
Schwarz="SCHWARZ"  
Gelb="GELB"}  

$c = @{
Haus="HAUS"  
Baum="BAUM"  
Zaun="ZAUN"}  

$root = 'D:\Ordner'  

gci $root -File -Recurse | %{
    if ($_.Directory.Name -match (($a.GetEnumerator() | %{[regex]::Escape($_.Value)}) -join '|') ){  
        $part1 = $matches
        if ($_.Directory.Name -match (($b.GetEnumerator() | %{[regex]::Escape($_.Value)}) -join '|') ){  
            $part2 = $matches
            if ($_.Directory.Name -match (($c.GetEnumerator() | %{[regex]::Escape($_.Value)}) -join '|') ){  
                $part3 = $matches
                $dest = "$root\123_${part1}_${part2}_${part3}_123"  
                if (!(Test-Path $dest)){md $dest -Force | out-null}
                $_ | move-item -destination $dest -Force
            }
        }
    }
}

Gruß l.
Member: functionstrut
functionstrut Nov 05, 2018 updated at 19:26:02 (UTC)
Goto Top
vielen Dank schonmal. Irgendwas haut aber nicht so richtig hin, kann es daran liegen das der Key Sonderzeichen hat und auch in " " steht? denn der Code so von dir kopiert funktioniert. Mit meinen Sonderzeichen als Key aber nicht.

Jep habs mal getestet. Füge ich irgenwo einfach ein ä ein dann findet das script keine treffer.
Mitglied: 137443
137443 Nov 06, 2018 updated at 06:25:38 (UTC)
Goto Top
Füge ich irgenwo einfach ein ä ein dann findet das script keine treffer.
Kann ich nicht bestätigen, dann muss das Encoding deiner Datei nicht stimmen. Umlaute werden nur mit korrektem Encoding gefunden und Sonderzeichen ebenso, außerdem werden diese korrekt für das Regex escaped.

Siehe Beispiel mit Sonderzeichen:

https://tio.run/##rZLRTtswFIbv/RSelanJhQO0d0iRaNfQIrFqaumQylDkhtPGKIkrx1 ...
Member: functionstrut
functionstrut Nov 06, 2018 at 09:26:00 (UTC)
Goto Top
das stimmt, so wie in deinem link, funktioniert es. Aber in diesem Fall:

https://tio.run/##rZLRTtswFIbv/RSelanJhQO0d0iRaNfQIrFqaumQylDkhtPGKIkrx1 ...

klappt die Ausgabe nicht. Ich habe im Key Sonderzeichen drin und nicht nur im Value. Könntest du anhand des skriptes im Link einmal schauen und es zum laufen bekommen?
Mitglied: 137443
137443 Nov 06, 2018 updated at 09:52:34 (UTC)
Goto Top
Zitat von @functionstrut:

das stimmt, so wie in deinem link, funktioniert es. Aber in diesem Fall:

https://tio.run/##rZLRTtswFIbv/RSelanJhQO0d0iRaNfQIrFqaumQylDkhtPGKIkrx1 ...

klappt die Ausgabe nicht.
Doch klappt doch, Ausgabe ist korrekt!
Ich habe im Key Sonderzeichen drin und nicht nur im Value.
Das ist wurscht. Der Key kommt hier gar nicht zum Einsatz, sondern nur der Value!! Du ymachst irgendwas falsch. Ich kann es hier leider nicht sehen, und ich kann überall Sonderzeichen oder sonst was einpflanzen geht einwandfrei. Was du natürlich beachten musst ist das in einer Hashtable natürlich keine doppelten Einträge geben darf.
Member: functionstrut
functionstrut Nov 06, 2018 updated at 10:10:14 (UTC)
Goto Top
Na Guck jetzt haben wir den Fehler gefunden face-smile denn der Ordner muss ja den Key enthalten und nicht den Value. Wie kann man das umändern? Das er nicht Nacht den values matched sondern nach den Keys und aber als Destination den jeweiligen value benutzt?

Wenn es einfacher ist: es würde auch ein einfaches multidimensional Array gehen, denn so habe ich es aktuell laufen welches mir aber zu lange dauert.

Edith: ich sehe auch gerade der Link aus meinem Kommentar war veraltet. Ich werde gleich den neuen nochmal schicken. Eventuell ist es dort dann besser ersichtlich.
Mitglied: 137443
137443 Nov 06, 2018 updated at 10:11:57 (UTC)
Goto Top
Zitat von @functionstrut:

Na Guck jetzt haben wir den Fehler gefunden face-smile denn der Ordner muss ja den Key enthalten und nicht den Value.
Tja wenn man das nicht schreibt weiß es keiner ...
Wie kann man das umändern?
Tipp damit du auch noch selber was zu knobeln hast: $_.Key face-wink
Member: functionstrut
functionstrut Nov 06, 2018 at 10:12:53 (UTC)
Goto Top
Mitglied: 137443
Solution 137443 Nov 06, 2018 updated at 10:18:27 (UTC)
Goto Top
Schade wäre nicht viel zu ändern gewesen ...
$a = @{
Eins="EINS"  
Zwei="ZWEI"  
Drei="DREI"}  

$b = @{
Blau="BLAU"  
Schwarz="SCHWARZ"  
Gelb="GELB"}  

$c = @{
Häus-Eins="HäUS-Zwö"  
Baum="BAUM"  
Zaun="ZAUN"}  

$root = 'D:\Ordner'  

$crit1 = (($a.GetEnumerator() | %{[regex]::Escape($_.Key)}) -join '|')  
$crit2 = (($b.GetEnumerator() | %{[regex]::Escape($_.Key)}) -join '|')  
$crit3 = (($c.GetEnumerator() | %{[regex]::Escape($_.Key)}) -join '|')  

gci $root -File -Recurse | %{
    if ($_.Directory.Name -match $crit1 ){
        $part1 = $matches
        if ($_.Directory.Name -match $crit2){
            $part2 = $matches
            if ($_.Directory.Name -match $crit3){
                $part3 = $matches
                $dest = "$root\123_$($a[$part1])_$($b[$part2])_$($c[$part3])_123"  
                if (!(Test-Path $dest)){md $dest -Force | out-null}
                $_ | move-item -destination $dest -Force -verbose
            }
        }
    }
}
Member: functionstrut
functionstrut Nov 08, 2018 updated at 11:36:44 (UTC)
Goto Top
ich danke dir recht herzlich face-smile Das script läuft super. Habe lediglich die Key`s auch noch in " " gesetzt. Mein altes Script hat durch diverse loops bis zu 2 Tage gebraucht und das hier braucht gerade mal 10 Minuten(liegt an meinen großen Vergleichstabellen).

$a = @{
"Eins" = "EINS"  
"Zwei" = "ZWEI"  
"Drei" = "DREI"}  

$b = @{
"Blau" = "BLAU"  
"Schwarz" = "SCHWARZ"  
"Gelb" = "GELB"}  

$c = @{
"Häus-Eins" = "HäUS-Zwö"  
"Baum" = "BAUM"  
"Zaun" = "ZAUN"}  

$root = 'D:\Ordner'  

$crit1 = (($a.GetEnumerator() | %{[regex]::Escape($_.Key)}) -join '|')  
$crit2 = (($b.GetEnumerator() | %{[regex]::Escape($_.Key)}) -join '|')  
$crit3 = (($c.GetEnumerator() | %{[regex]::Escape($_.Key)}) -join '|')  

gci $root -File -Recurse | %{
    if ($_.Directory.Name -match $crit1 ){
        $part1 = $matches
        if ($_.Directory.Name -match $crit2){
            $part2 = $matches
            if ($_.Directory.Name -match $crit3){
                $part3 = $matches
                $dest = "$root\123_$($a[$part1])_$($b[$part2])_$($c[$part3])_123"  
                if (!(Test-Path $dest)){md $dest -Force | out-null}
                $_ | move-item -destination $dest -Force -verbose
            }
        }
    }
}
Member: functionstrut
functionstrut Feb 04, 2019 at 21:01:07 (UTC)
Goto Top
ich hätte da noch eine optionale frage. Ist es möglich die Keys, welche ja zum "suchen" genutzt werden, teilweise durch regex zu ersetzen? also angenommen vor jedem key ist entweder ein Fragezeichen oder ein Ausrufezeichen. Das wäre als regex ja [?!]. baue ich diese regexfunktion aber mit in die Keys ein dann wird nichts gefunden.