Benutzer mit den meisten Antworten
Unbekannte Verzeichnisse mit bekannten und unbekannten Dateien verschieben

Frage
-
Hallo Powerschell Profis,
ich möchte Verzeichnisse mit unbekannten Verzeichnisnamen, welche Dateien mit der Endung *.MP3 und weitere unbekannte Dateiendungen enthalten, verschieben. Die Identifizierung funktioniert also über die MP3 Dateien. Dabei liegen die MP3 Dateien mal direkt im unbekannten Verzeichnis und mal auf weitere Unterverzeichnisse verteilt. (Können auch mal mehr Ebenen als im unteren Beispiel sein). Beim Verschieben soll nur die Verzeichnisstruktur der Verzeichnisse mit MP3 Dateien und deren erstes, übergeordnetes Verzeichnis erhalten bleiben. (Beispiel aus unterem Verzeichnis: „\UnbekanntesVerzeichnisMitUnterverzeichnissen2“ Falls das nicht geht auch gerne das erste Verzeichnis, welches Unterverzeichnisse mit MP3´s enthält: (\UnbekanntesVerzeichnisMitUnterverzeichnissen“)
Ich habe hier und im Netz leider nur ähnliche Scripte gefunden, die ich nicht anzupassen in der Lage war.
Zur Zeit habe ich dies über den Copy Befehl gelöst, da Move-Item den Rekursiv Befehl ja nicht beherrscht. (Vermutlich aus gutem Grund). Dies funktioniert zwar, allerdings muss ich dann nachträglich die Dateien im Quellverzeichnis löschen und kann nur raten welche ich löschen muss. Desweiteren wird die komplette Verzeichnisstruktur kopiert, Verzeichnisse die keine MP3 Dateien enthalten werden als leere Verzeichnisse kopiert und nachträglich gelöscht.
Ist dies überhaupt zu realisieren? Für jede Hilfe wäre ich dankbar! Hoffe nicht zu viel geschrieben und die Forenregeln so gut wie möglich beachtet zu haben.
Verzeichnisstruktur Quelle:
D:\BekanntesQuelleverzeichnis
----\UnbekanntesVerzeichnisMitUnterverzeichnissen
-------\UnbekanntesVerzeichnisMitUnterverzeichnissen2
---------\UnbekanntesUnterverzeichnis1MP3
-----------\Datei.mp3---------\UnbekanntesUnterverzeichnis2MP3
------------\Datei.mp3
---------\UnbekanntesUnterverzeichnis3MP3
-----------\Datei.mp3
-----------------------------------------------------------------------
----\UnbekanntesVerzechnisNichtVerschieben
----\UnbekanntesVerzechnisNichtVerschieben2
-----------------------------------------------------------------------
----\UnbekanntesVerzeichnisMitMP3Nummer2
------\Datei1.mp3
------\Datei2.mp3Gewünschte Struktur Ziel:
E:\BekanntesZielverzeichnis
------\UnbekanntesVerzeichnisMitUnterverzeichnissen2
---------\UnbekanntesUnterverzeichnis1MP3
-----------\Datei.mp3---------\UnbekanntesUnterverzeichnis2MP3
-----------\Datei.mp3
---------\UnbekanntesUnterverzeichnis3MP3
-----------\Datei.mp3
--------------------------------------------------------------------------
------\UnbekanntesVerzeichnisMitMP3Nummer2
---------\Datei1.mp3
---------\Datei2.mp3Code wie er jetzt verwendet wird aber eigentlich unzureichend ist:
$quellpfad = 'D:\Quellverzeichnis' $zielpfad = 'E:\Zielverzeichnis' copy-item -recurse -filter *.mp3 -Path "D:\Quellverzeichnis\" "E:\Zielverzeichnis" –force get-childitem -path "D:\Quellverzeichnis\" -include *.mp3 -recurse | remove-item copy-item -recurse -filter *.m3u -Path „D:\Quellverzeichnis\“ „E:\Zielverzeichnis\“ –force get-childitem -path „D:\Quellverzeichnis\“ -include *.m3u -recurse | remove-item copy-item -recurse -filter *.jpg -Path „D:\Quellverzeichnis\“ „E:\Zielverzeichnis\“ –force get-childitem -path „D:\Quellverzeichnis\“ -include *.jpg -recurse | remove-item #Löscht leere Verzeichnisse aus E:\Zielverzeichnis, welche beim kopieren mit angelegt wurden Get-ChildItem -path $quellpfad,$zielpfad -recurse | Where {$_.PSIsContainer -and ` @(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} | Remove-Item -recurse
Antworten
-
Mann so viel Fragen …
Aber gut du hast es so gewollt ! ;-))
Es ist wie mit allen Dingen im Leben, man kann Theoretisch Fahrrad fahren, ist ja ganz leicht, man sieht es ja bei anderen…. ;-))
Aber richtig Fahrrad fahren, lernt man nur durch Fahrrad fahren!Soll heißen: auch hier bei PowerShell lernt man die Sprache erst richtig kennen indem man Sie benutzt.
PowerShell basiert auf dem .NET Framework!
Jedes PowerShell Ergebnis und jede PowerShell Variable ist eine Klasse (Objekt) aus dem .NET Framework.
Du kannst also zusätzlich zu den cmdlets die dir PowerShell bietet, auch jede .NET Klasse benutzen!
Um heraus zu finden welche Klasse des .NET Frameworks die PowerShell gerade verarbeitet,
kann man die Funktion GetType() benutzen sie ist in jedem Objekt vorhanden."Hallo".GetType() # ergibt das Ergebnis Name=String ! Das ist der .NET Type System.String
Besser und leichter ist es das cmdlet Get-Member zu benutzen:
"Hallo" | Get-Member #TypeName: System.String #Sagt dir was für ein .NET Typ du gerade verarbeitest.
In diesem Objekt gibt es Properties und Methoden.
Propertys sind wie Attribute die man "nur" abfragen und setzen kann( Gewicht,Farbe,Grösse,Alter ...).
Methoden führen eine Aktion aus (Gehe(4m),Lenke.Links(35°),Hüpfe()...)
Nun nimmst du deine Information und gibt’s folgende Zeile in der Internetsuchmaschine ein:MSDN System.String
(MSDN ist die Abkürzung für Microsoft Developer Network)Die sollte dich zu der Dokumentation der Klasse System.String führen:
http://msdn.microsoft.com/de-de/library/system.string.aspxDort findest du alle Nützlichen Methoden um Strings zu verarbeiten!
Auch die Eigenschaften sind dort erklärt. z.B. String.Length Oder String.Chars.
Methoden müssen mit Klammern geschrieben werden!!!!!!!!!! Properties nicht!Get-Member ist also ein sehr wichtiger Befehl!
http://technet.microsoft.com/de-de/library/dd315243.aspx# Methoden "Hallo".IndexOf("a") # Welche position hat der Buchstabe a? "Hallo".Replace("l","s") # alle Buchstaben l durch s ersetzen # Properties "Hallo".length # länge des Strings ermitteln
Wenn du dort in der Dokumentation auf die Methode replace() Klickst bekommst du die Erklärung wie sie funktioniert!
Man könnte das auch so schreiben:# Dies benutzt intern auch die String.Replace('l','s') Methode! "Hallo" -replace 'l','s'
Fast genauso wichtig ist wir Get-Member ist das Select-Objekt *
Bei Get-Member siehst du „nur“ die Properties und Methoden des Objekt aber nicht welche Werte Sie haben!
Dies bekommst du mit Select-Objekt * heraus.
Mach mal folgendes:# Hier siehst du das du ein Objekt TypeName: System.IO.DirectoryInfo bekommst. (Also ein Directory Objekt) Get-Item 'C:\windows' | Get-Member # Hier siehst du welche Werte die Propertys haben Get-Item 'C:\windows' | Select *
Dort findest du das Property Fullname (also den kompletten Pfad zum Directory) Das $_ Zeichen enthält das Objekt das sich gerade in der Pipeline befindet. Also kann ich Schreiben:
Get-Item 'C:\windows' | Select Fullname # oder Get-Item 'C:\windows' | Foreach {$_.Fullname}
Die Drei Wichtigsten cmdlets:
http://www.powershellpraxis.de/Die-drei-wichtigsten-Cmdlets.946.0.html
• get-help
• get-command
• get-memberPowerShell Praxis:
http://www.powershellpraxis.de/My-Powershell.943.0.htmlWindows PowerShell-Benutzerhandbuch
http://technet.microsoft.com/de-de/library/cc196356.aspx-----------------------------------------------------------------------------------------
>>>> Und wird mit .replace im Zielverzeichnis einfach ein Verzeichnis überschrieben, falls es das schon gibt?
Nein! Replace ist eine String Funktion diese ersetze nur den Text des Quellfades durch den Text des Zielpfades. Mit diesem bearbeiteten String (Pfad) arbeiten dann die cmdlets/Funktionen weiter.
>>>> Und hätte bei MoveToPath nicht das ganze Verzeichnis mit MP3 verschoben werden müssen, anstatt ein leeres im Quellverzeichnis zurück zu bleiben?
Nein ! Ich verschiebe dort nur die Aktuell von Get-ChildItem gefunden Datei (FullName / path der Datei) !
>>>>Was macht hier Split-Path ?
Siehe: Get-Help Split-Path -full
>>>> und was -Parent?
Siehe: Get-help Split-Path -Parameter parent
>>>> Wäre Parent nicht genau das, was ich möchte? MP3 und zusätzlichen Dateien plus eine Verzeichnis darüber zu verschieben. (Oder wie hier, neu anzulegen).
Ja ! ist aber nicht so einfach …. ;-)) Dann halt So:
$quellpfad = 'D:\Quellverzeichnis' $zielpfad = 'E:\Zielverzeichnis' # Alle Verzeichnisse ermitteln in denen die gesuchtenDateien vorkommen und in Variable $Verzeichnisse speichern # Zuerst alle Dateien Finden $Verzeichnisse = Get-ChildItem -Path $quellpfad -include *.vb,*.sln,*.mp3,*.m3u,*.jpg -recurse | # Dann von den Gefundenen Dateien die Verzeichnisse auslesen (Parent) Foreach-Object {Split-Path -Path $_.fullname -Parent } # Doppelte Verzeichnissnamen aus dem Array entfernen $Verzeichnisse = $Verzeichnisse | Select-Object -Unique # Alle Verzeichnisse im Array durchlaufen $Verzeichnisse | Foreach-Object { # Verzeichniss Strucktur anlegen New-Item $(($_).replace($quellpfad,$zielpfad)) -ItemType "directory" -Force -ErrorAction SilentlyContinue # alle Dateien des Aktuellen Verzeichnisses in das neue Verschieben Get-ChildItem $_ | where { ! $_.PSIsContainer } | foreach { Move-Item -Path $_.fullname -Destination $(($_.fullname).replace($quellpfad,$zielpfad)) -Force } } # end foreach # im $zielpfad befinden sich keine leeren Verzeichnisse!!! # deshalb muss auch nur das $quellpfad Verzeichniss bearbeitet werden! # Schleife um Recursive alle leeren Verzeichnisse aus einem Verzeichniss zu entfernen Do { # Alle Verzeichnisse recursive aus dem Wurzelverzeichniss lesen $LIST=GET-CHILDITEM $quellpfad –recurse –force | where { $_.PSISContainer } # $DONE wird als Flag (Indikator) benutzt, ob Leere Verzeichnisse vorhanden sind ($True) oder nicht ($False) $DONE=$False # Alle Verzeichnisse durchlaufen foreach ($Directory in $LIST) { # Wenn das Verzeichniss keine Dateien (0) UND keine UnterVerzeichnisse (0) enthält, ist es leer! IF ( $Directory.Getfiles().Count –eq 0 –and $Directory.GetDirectories().Count –eq 0) { # Leeres Verzeichniss wird gelöscht $("REMOVE-ITEM " + $Directory.Fullname) REMOVE-ITEM $Directory.FullName -Force # wir haben ein leeres Verzeichniss gefunden als muss die schleife nochmal durchlaufen werden $DONE=$True } # End IF } # end Foreach # Wenn kein leeres Verzeichniss gefunden wurde, # dann ist $DONE nicht auf $True gesetzt worden und die Schleife endet } until ($DONE –eq $False)
Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
- Bearbeitet Peter Kriegel Freitag, 11. Mai 2012 05:06
- Als Antwort markiert Sönke T Freitag, 11. Mai 2012 12:31
Alle Antworten
-
Bitte an eine Testverzeichniss Testen!
Beispiel wie man Dateien recursive löschen oder verschieben kann:
$quellpfad = 'D:\Quellverzeichnis' $zielpfad = 'E:\Zielverzeichnis' # Dateien recursive verschieben geht so: Get-ChildItem -Path $quellpfad -include *.mp3,*.m3u,*.jpg -recurse | foreach { # Datei Verschieben Move-Item -Path $_.fullname -Destination $($_.fullname.replace($quellpfad,$zielpfad)) } # end foreach
Lösung für dein Problem !?:
$quellpfad = 'D:\Quellverzeichnis' $zielpfad = 'E:\Zielverzeichnis' # Dateien recursive verschieben und Verzeichnisse für sie anlegen # Dabei entstehen keine leeren verzeichnisse und die selbe Strucktur wie in dem Quellverzeichnis! Get-ChildItem -Path $quellpfad -include *.mp3,*.m3u,*.jpg -recurse | foreach { # ZielPfad für die Datei erstellen (Wurzelverzeichnisse durch replace austauschen) $MoveToPath = $(($_.fullname).replace($quellpfad,$zielpfad)) # Ziel directory der Datei anlegen wenn es noch nicht existiert New-Item -Path $(Split-Path -Path $MoveToPath -Parent) -ItemType "directory" -ErrorAction SilentlyContinue # Datei Verschieben Move-Item -Path $_.fullname -Destination $MoveToPath } # end foreach
Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '- Bearbeitet Peter Kriegel Dienstag, 8. Mai 2012 15:08
- Als Antwort markiert Sönke T Dienstag, 8. Mai 2012 21:34
- Tag als Antwort aufgehoben Sönke T Freitag, 11. Mai 2012 12:30
-
Hallo Peter,
Erst mal ein großes Danke schön für deine Antwort! Dein Script sieht schon mal sauberer aus als meins.
Allerdings macht es das gleiche wie meins, nur das im Zielverzeichnis keine leeren Verzeichnisse gelöscht werden müssen. (Zumindest so weit, wie ich dein Vorgehensweise verstehe).
Leere Verzeichnisse bleibe im Quellverzeichnis zurück, was nicht weiter schlimm wäre, lösche ich diese eben wieder.
Mein Hauptanliegen wurde aber nicht erfüllt! Die Endungen, nach denen du und ich rekurisv filtern wurden von mir nur aus mangelndem Wissen eingefügt um zum Ziel zu kommen. (Da mir diese die wichtigsten sind). Eigentlich möchte ich ja alle Verzeichnisse verschieben, die MP3´s enthalten plus allen unbekannten Dateien. Ist z.B. eine *.Log, *.txt oder eine *.Jpeg anstatt einer *.JPG im Verzeichnis zusätzlich enthalten, würden diese nicht verschoben. Auch werden diese nicht im Quellverzeichnis gelöscht. Darauf kommt es mir aber ja gerade an. Ich möchte nicht die Reste im Quellverzeichnis manuell löschen.
Das I-Tüpfelchen wäre dann noch, dass nicht genau die gleiche Verzeichnisstruktur im Zielverzeichnis erstellt wird, sondern immer ein Verzeichnis über dem ersten Verzeichnis, das MP3 und alle unbekannten Dateien enthält. (Im Beispiel also ab Hörbuchname). Notfalls kann ich hierauf aber auch verzichten.D:\Quellverzeichnis
----\VerzeichnisKannWeg
------\Hörbuchname
---------\CD1
---------\CD2Wärst du so nett und erklärst mir, wie man auf die einzelnen Funktionen kommt und was sie machen? Auf diese wäre ich als Anfänger nie gekommen.
foreach { $MoveToPath = $(($_.fullname).replace($quellpfad,$zielpfad))
In keiner Hilfe oder mit get-help oder mit Get-member finde ich $MoveToPath oder $_.fullname. Und woher weist du, dass es .replace gibt?
Und hätte bei MoveToPath nicht das ganze Verzeichnis mit MP3 verschoben werden müssen, anstatt ein leeres im Quellverzeichnis zurückzu bleiben? Und wird mit .replace im Zielverzeichnis einfach ein Verzeichnis überschrieben, falls es das schon gibt?New-Item -Path $(Split-Path -Path $MoveToPath -Parent) -ItemType "directory" -ErrorAction SilentlyContinue
Was macht hier Split-Path und was -Parent? Wäre Parent nicht genau das, was ich möchte? MP3 und zusätzlichen Dateien plus eine Verzeichnis darüber zu verschieben. (Oder wie hier, neu anzulegen). -
Mann so viel Fragen …
Aber gut du hast es so gewollt ! ;-))
Es ist wie mit allen Dingen im Leben, man kann Theoretisch Fahrrad fahren, ist ja ganz leicht, man sieht es ja bei anderen…. ;-))
Aber richtig Fahrrad fahren, lernt man nur durch Fahrrad fahren!Soll heißen: auch hier bei PowerShell lernt man die Sprache erst richtig kennen indem man Sie benutzt.
PowerShell basiert auf dem .NET Framework!
Jedes PowerShell Ergebnis und jede PowerShell Variable ist eine Klasse (Objekt) aus dem .NET Framework.
Du kannst also zusätzlich zu den cmdlets die dir PowerShell bietet, auch jede .NET Klasse benutzen!
Um heraus zu finden welche Klasse des .NET Frameworks die PowerShell gerade verarbeitet,
kann man die Funktion GetType() benutzen sie ist in jedem Objekt vorhanden."Hallo".GetType() # ergibt das Ergebnis Name=String ! Das ist der .NET Type System.String
Besser und leichter ist es das cmdlet Get-Member zu benutzen:
"Hallo" | Get-Member #TypeName: System.String #Sagt dir was für ein .NET Typ du gerade verarbeitest.
In diesem Objekt gibt es Properties und Methoden.
Propertys sind wie Attribute die man "nur" abfragen und setzen kann( Gewicht,Farbe,Grösse,Alter ...).
Methoden führen eine Aktion aus (Gehe(4m),Lenke.Links(35°),Hüpfe()...)
Nun nimmst du deine Information und gibt’s folgende Zeile in der Internetsuchmaschine ein:MSDN System.String
(MSDN ist die Abkürzung für Microsoft Developer Network)Die sollte dich zu der Dokumentation der Klasse System.String führen:
http://msdn.microsoft.com/de-de/library/system.string.aspxDort findest du alle Nützlichen Methoden um Strings zu verarbeiten!
Auch die Eigenschaften sind dort erklärt. z.B. String.Length Oder String.Chars.
Methoden müssen mit Klammern geschrieben werden!!!!!!!!!! Properties nicht!Get-Member ist also ein sehr wichtiger Befehl!
http://technet.microsoft.com/de-de/library/dd315243.aspx# Methoden "Hallo".IndexOf("a") # Welche position hat der Buchstabe a? "Hallo".Replace("l","s") # alle Buchstaben l durch s ersetzen # Properties "Hallo".length # länge des Strings ermitteln
Wenn du dort in der Dokumentation auf die Methode replace() Klickst bekommst du die Erklärung wie sie funktioniert!
Man könnte das auch so schreiben:# Dies benutzt intern auch die String.Replace('l','s') Methode! "Hallo" -replace 'l','s'
Fast genauso wichtig ist wir Get-Member ist das Select-Objekt *
Bei Get-Member siehst du „nur“ die Properties und Methoden des Objekt aber nicht welche Werte Sie haben!
Dies bekommst du mit Select-Objekt * heraus.
Mach mal folgendes:# Hier siehst du das du ein Objekt TypeName: System.IO.DirectoryInfo bekommst. (Also ein Directory Objekt) Get-Item 'C:\windows' | Get-Member # Hier siehst du welche Werte die Propertys haben Get-Item 'C:\windows' | Select *
Dort findest du das Property Fullname (also den kompletten Pfad zum Directory) Das $_ Zeichen enthält das Objekt das sich gerade in der Pipeline befindet. Also kann ich Schreiben:
Get-Item 'C:\windows' | Select Fullname # oder Get-Item 'C:\windows' | Foreach {$_.Fullname}
Die Drei Wichtigsten cmdlets:
http://www.powershellpraxis.de/Die-drei-wichtigsten-Cmdlets.946.0.html
• get-help
• get-command
• get-memberPowerShell Praxis:
http://www.powershellpraxis.de/My-Powershell.943.0.htmlWindows PowerShell-Benutzerhandbuch
http://technet.microsoft.com/de-de/library/cc196356.aspx-----------------------------------------------------------------------------------------
>>>> Und wird mit .replace im Zielverzeichnis einfach ein Verzeichnis überschrieben, falls es das schon gibt?
Nein! Replace ist eine String Funktion diese ersetze nur den Text des Quellfades durch den Text des Zielpfades. Mit diesem bearbeiteten String (Pfad) arbeiten dann die cmdlets/Funktionen weiter.
>>>> Und hätte bei MoveToPath nicht das ganze Verzeichnis mit MP3 verschoben werden müssen, anstatt ein leeres im Quellverzeichnis zurück zu bleiben?
Nein ! Ich verschiebe dort nur die Aktuell von Get-ChildItem gefunden Datei (FullName / path der Datei) !
>>>>Was macht hier Split-Path ?
Siehe: Get-Help Split-Path -full
>>>> und was -Parent?
Siehe: Get-help Split-Path -Parameter parent
>>>> Wäre Parent nicht genau das, was ich möchte? MP3 und zusätzlichen Dateien plus eine Verzeichnis darüber zu verschieben. (Oder wie hier, neu anzulegen).
Ja ! ist aber nicht so einfach …. ;-)) Dann halt So:
$quellpfad = 'D:\Quellverzeichnis' $zielpfad = 'E:\Zielverzeichnis' # Alle Verzeichnisse ermitteln in denen die gesuchtenDateien vorkommen und in Variable $Verzeichnisse speichern # Zuerst alle Dateien Finden $Verzeichnisse = Get-ChildItem -Path $quellpfad -include *.vb,*.sln,*.mp3,*.m3u,*.jpg -recurse | # Dann von den Gefundenen Dateien die Verzeichnisse auslesen (Parent) Foreach-Object {Split-Path -Path $_.fullname -Parent } # Doppelte Verzeichnissnamen aus dem Array entfernen $Verzeichnisse = $Verzeichnisse | Select-Object -Unique # Alle Verzeichnisse im Array durchlaufen $Verzeichnisse | Foreach-Object { # Verzeichniss Strucktur anlegen New-Item $(($_).replace($quellpfad,$zielpfad)) -ItemType "directory" -Force -ErrorAction SilentlyContinue # alle Dateien des Aktuellen Verzeichnisses in das neue Verschieben Get-ChildItem $_ | where { ! $_.PSIsContainer } | foreach { Move-Item -Path $_.fullname -Destination $(($_.fullname).replace($quellpfad,$zielpfad)) -Force } } # end foreach # im $zielpfad befinden sich keine leeren Verzeichnisse!!! # deshalb muss auch nur das $quellpfad Verzeichniss bearbeitet werden! # Schleife um Recursive alle leeren Verzeichnisse aus einem Verzeichniss zu entfernen Do { # Alle Verzeichnisse recursive aus dem Wurzelverzeichniss lesen $LIST=GET-CHILDITEM $quellpfad –recurse –force | where { $_.PSISContainer } # $DONE wird als Flag (Indikator) benutzt, ob Leere Verzeichnisse vorhanden sind ($True) oder nicht ($False) $DONE=$False # Alle Verzeichnisse durchlaufen foreach ($Directory in $LIST) { # Wenn das Verzeichniss keine Dateien (0) UND keine UnterVerzeichnisse (0) enthält, ist es leer! IF ( $Directory.Getfiles().Count –eq 0 –and $Directory.GetDirectories().Count –eq 0) { # Leeres Verzeichniss wird gelöscht $("REMOVE-ITEM " + $Directory.Fullname) REMOVE-ITEM $Directory.FullName -Force # wir haben ein leeres Verzeichniss gefunden als muss die schleife nochmal durchlaufen werden $DONE=$True } # End IF } # end Foreach # Wenn kein leeres Verzeichniss gefunden wurde, # dann ist $DONE nicht auf $True gesetzt worden und die Schleife endet } until ($DONE –eq $False)
Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
- Bearbeitet Peter Kriegel Freitag, 11. Mai 2012 05:06
- Als Antwort markiert Sönke T Freitag, 11. Mai 2012 12:31
-
Hallo,
vielen Dank für die ausführlichen Erklärungen und Links! Dies bringt mir die ganze Sache sehr viel näher als die normale Powershell Hilfe. Vor allen Dingen der Link zu den .Netframwork System Strings!!!. Hier habe ich jetzt Ansätze zum üben.
Zum Script:
Im Ziel Bereich funktioniert nun fast alles. Dadurch, dass weiterhin jede weitere Endung außer *.MP3 im Quellverzeichnis angegeben werden muss, werden alle weiteren, nicht angegebenen, zwangsläufig ausgeschlossen. Diese werden nicht verschoben und bleiben in der Quelle und fehlen evtl. im Ziel.
Macht aber nichts, ich werde nun einfach das Script darum erweitern, dass Dateien, die älter als 10 Tage sind, gelöscht werden. Danach sollen gleich wieder alle leeren Verzeichnisse gelöscht werden. Und Primär geht es mir ja auch um die MP3, JPG, und M3U Dateien.
Scheint also nicht nicht so einfach zu sein, ein Verzeichnis nur anhand einer Endung (*.MP3) zu identifizieren und es dann mit allen weiteren, unbekannten Endungen zu verschieben ohne diese anzugeben.
-
Ich habe das Skript eigentlich so geschrieben:
Wenn in einem Verzeichniss eine Datei mit der einer der gesuchten Dateiendung vorkommt, dann werden ALLE Dateien indiesem Verzeichniss in das neue Verschoben.
Unterverzeichnisse werden dort nicht behandelt.Bei mir hat das so geklappt!
Dann muss ich woh noch mal ran....?
Bitte demarkiere die Markierte Antwort und Markiere die beste Antwort als Antwort! (Mehrfachmarkierungen sind möglich)
Das hilft anderen Forenlesern gleich die beste Antwort zu finden.Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' ' -
Hi,
danke für das Angebot, nehme ich gerne an, wenn es nicht zu viel mühe macht! Da ist mehr support als ich zu wünschen gewagt hätte.
Es bleiben weiter nicht explizit (Im Bsp. *.rar) angegebene Dateiendung im Quellverzeichnis zurück und diese sind auch im Zielverzeichnis nicht da. Diese Verzeichnisse können dann natürlich auch nicht gelöscht werden, da sie ja nicht leer sind.
Hier noch mal die Beispiele wie es nun aussieht. VerzeichnisKannweg ist im Ziel immer noch da. (Habe ich ja gesagt, notfalls nicht so schlimm).
Evtl. liegt es ja daran, dass die Unterverzeichnisse dort nicht behandelt werden.D:\Quellverzeichnis
----\VerzeichnisKannWeg
------\Hörbuchname
---------\CD1
----------\Datei1.mp3
----------\Datei2.rar
---------\CD2
----------\Daei1.mp3D:\Zielverzeichnis
----\VerzeichnisKannWeg
------\Hörbuchname
---------\CD1
----------\Datei1.mp3
---------\CD2
----------\Datei1.mp3 -
Ich habe noch 1 Bug gefunden.
Der erste Bug ist: Das String.Replace ist case sensitiv (beachtet Groß- und Kleinschreibung)
Wenn der Datei Pfad (von der Festplatte) und die Variabel $QuellPfad unterschiedlich geschrieben sind, dann ersetzt replace nicht!In der Schleife die die leeren Ordner löscht war auch noch ein unwichtiger Fehler.(der Löschpfad war $Null)
$quellpfad = 'c:\temp\quelle' $zielpfad = 'c:\temp\ziel' # Alle Verzeichnisse ermitteln in denen die gesuchtenDateien vorkommen und in Variable $Verzeichnisse speichern # Zuerst alle Dateien Finden $Verzeichnisse = Get-ChildItem -Path $quellpfad -include *.mp3,*.m3u,*.jpg -recurse | # Dann von den Gefundenen Dateien die Verzeichnisse auslesen (Parent) Foreach-Object {Split-Path -Path $_.fullname -Parent } # Doppelte Verzeichnissnamen aus dem Array entfernen $Verzeichnisse = $Verzeichnisse | Select-Object -Unique # Alle Verzeichnisse im Array durchlaufen $Verzeichnisse | Foreach-Object { # string.replace ist nicht mit verschiedenen gross / Kleinschreibungen zu gebrauchen # regex kann nicht genommen werden wegen der schrägstriche (backslasches) in Pfaden # deshalb ersetze ich den Text so umständlich. $Ziel = $zielpfad + $_.substring($quellpfad.Length,$_.length - $quellpfad.Length) # Verzeichniss Strucktur anlegen New-Item $Ziel -ItemType "directory" -Force -ErrorAction SilentlyContinue # alle Dateien des Aktuellen Verzeichnisses in das neue Verschieben Get-ChildItem $_ | where { ! $_.PSIsContainer } | foreach { Move-Item -Path $_.fullname -Destination $Ziel -Force } } # end foreach # im $zielpfad befinden sich keine leeren Verzeichnisse!!! # deshalb muss auch nur das $quellpfad Verzeichniss bearbeitet werden! # Schleife um Recursive alle leeren Verzeichnisse aus einem Verzeichniss zu entfernen Do { # Alle Verzeichnisse recursive aus dem Wurzelverzeichniss lesen $LIST=GET-CHILDITEM $quellpfad –recurse –force | where { $_.PSISContainer } # $DONE wird als Flag (Indikator) benutzt, ob Leere Verzeichnisse vorhanden sind ($True) oder nicht ($False) $DONE=$False # Alle Verzeichnisse durchlaufen foreach ($Directory in $LIST) { if (!($Directory -eq $Null)) { # Wenn das Verzeichniss keine Dateien (0) UND keine UnterVerzeichnisse (0) enthält, ist es leer! IF ( $Directory.Getfiles().Count –eq 0 –and $Directory.GetDirectories().Count –eq 0) { # Leeres Verzeichniss wird gelöscht $("REMOVE-ITEM " + $Directory.Fullname) REMOVE-ITEM $Directory.FullName -Force # wir haben ein leeres Verzeichniss gefunden als muss die schleife nochmal durchlaufen werden $DONE=$True } # End IF } # End IF } # end Foreach # Wenn kein leeres Verzeichniss gefunden wurde, # dann ist $DONE nicht auf $True gesetzt worden und die Schleife endet } until ($DONE –eq $False)
Nimm Bitte zum Testen Frische Ordner! Sonnst weiss man nicht was passiert!
den rest muss du selber finden ....
Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
- Bearbeitet Peter Kriegel Freitag, 11. Mai 2012 14:00