evolution
Goto Top

Bestimmte Dateien aus Unterverzeichnissen verschieben und restliche Ordner und Dateien löschen

Hallo,

ist es möglich per Batch oder PowerShell bestimmte Inhalte (Dateien) aus Ordnern in eine darunterliegende Ebene zu verschieben?

Konkret geht es um folgendes Problem.

Wir haben durch eine alte Backup-Software ca. 2000 automatisch erzeugten Verzeichnisse.

\\srv52.local.local\Backup.1521-BCK-0.11.fs\Backup.1521-BCK-0.11.fs\
\\srv52.local.local\Backup.1522-BCK-0.12.fs\Backup.1522-BCK-0.12.fs\
\\srv52.local.local\Backup.FA1522-BCKC-0.12.fas\Backup.FA1522-BCKC-0.12.fas\
etc..
Die Namen der einzelnen Verzeichnisse sind nicht gleich. Lediglich die Unterverzeichnisse tragen immer den selben Namen


In jedem Verzeichnis sind zip Dateien und .voc Dateien. manchmal gibt es auch noch einen 2. Unterordner mit irgendwelchen unwichtigen Logfiles..

Nun würden wir gerne den Inhalt der 2. Ebene (aber nur die .zip-Dateien) in den Hauptordner verschieben und alles andere komplett löschen. Es soll nur das Hauptverzeichnis mit den Zip-Dateien übrig bleiben.

Geht das mit einem Tool oder per Batch/Script?

Danke

Content-ID: 265327

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

Ausgedruckt am: 22.11.2024 um 11:11 Uhr

Penny.Cilin
Penny.Cilin 05.03.2015 um 14:37:27 Uhr
Goto Top
Hallo,

hast Du mal die Suchfunktion benutzt? Die Frage kommt jede Woche.


Gruss Penny.
evolution
evolution 05.03.2015 um 19:32:00 Uhr
Goto Top
Hab ich, aber nicht wirklich was gefunden, da ich nicht weiß nach was ich genau suchen muss
colinardo
colinardo 06.03.2015, aktualisiert am 30.03.2015 um 16:17:32 Uhr
Goto Top
Hallo evolution,
kein Thema... kannst du so mit Powershell machen.
Hinweis die Befehle sind nicht "scharf" geschaltet, sie zeigen nur an was geschehen würde. Wenn es deiner Vorstellung entspricht, einfach das -Whatif am Ende der beiden Befehle entfernen.
gci 'C:\ordner\*\*.zip' | %{  
    move-item $_.Fullname $_.Directory.Parent.FullName -WhatIf
    remove-Item $_.Directory -Recurse -Force -WhatIf
}
Grüße Uwe
evolution
evolution 08.03.2015 um 21:16:43 Uhr
Goto Top
Vielen Dank, ich habe es mal mit einem Testordner versucht, aber ich glaube da ist irgendwie ein Fehler drin.

Wenn ich das Script ausführe kopiert es nur die erste Zip-Datei aus dem Unterordner und löscht dann den Ordner.
Die restlichen Dateien, die darin enthalten sind, sind dann leider auch weg..

In dem Ordner sind also immer unterschiedlich viele Zip-Dateien drin, die verschoben werden sollen
colinardo
colinardo 08.03.2015, aktualisiert am 31.03.2015 um 13:12:48 Uhr
Goto Top
Zitat von @evolution:
Wenn ich das Script ausführe kopiert es nur die erste Zip-Datei aus dem Unterordner und löscht dann den Ordner.
Die restlichen Dateien, die darin enthalten sind, sind dann leider auch weg..
Ahh OK, dann habe ich dich missverstanden, dachte es geht immer nur um eine einzelne ZIP-Datei, sorry im Eifer des Gefechts überlesen..
In dem Fall ...
gci 'C:\rootordner' | ?{$_.PSIsContainer} | %{  
    move-item -Path "$($_.Fullname)\*.zip" -Destination $_.Parent.FullName  
    remove-Item $_.Fullname -Recurse -Force
}
Grüße Uwe
k.arkenau
k.arkenau 30.03.2015 um 15:37:06 Uhr
Goto Top
Ich hänge mich hier mal dran, da ich das gleiche vorhabe...ich habe das script von colinardo so angepasst

gci 'C:\test\000\*.pdf' | %{
move-item $_.Fullname $_.Directory.Parent.FullName -WhatIf
remove-Item $_.Directory -Recurse -Force -WhatIf

und in eine batch Datei gepackt. Wenn ich jedoch versuche, diese auszuführen, erscheint die Meldung, das der Befehl gci nicht gefunden wurde oder falsche geschrieben ist.

Was habe ich falsch gemacht?
114757
114757 30.03.2015 aktualisiert um 16:15:28 Uhr
Goto Top
Zitat von @k.arkenau:

Ich hänge mich hier mal dran, da ich das gleiche vorhabe...ich habe das script von colinardo so angepasst
Was habe ich falsch gemacht?
Min Jung, das ist kein Batch sondern Powershell !

Gruß jodel32
k.arkenau
k.arkenau 30.03.2015 um 17:08:36 Uhr
Goto Top
Moin,

ok, da liegt der Hase im Pfeffer....

Leider bin ich newbie was PowerShell angeht....und würde das am liebsten als Batch durchführen.

Kennt da jemand einen Weg per Batch das gleiche zu erreichen?
colinardo
colinardo 30.03.2015, aktualisiert am 01.04.2015 um 17:44:07 Uhr
Goto Top
Zitat von @k.arkenau:

Kennt da jemand einen Weg per Batch das gleiche zu erreichen?
Hallo zusammen,
Powershell kannst du ganz leicht in deine Batch einbauen:
powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\rootordner' | ?{$_.PSIsContainer} | %%{$path=$_.Fullname + '\*.pdf'; move-item -Path $path -Destination $_.Parent.FullName; remove-Item $_.Fullname -Recurse -Force}}"  
Grüße Uwe

Solltest du die Powershell-Executionpolicy noch nicht freigeschaltet haben und bei der Ausführung einen Fehler deswegen erhalten , beachte bitte folgende Hinweise:

Noch als kleine Einführung in Powershell-Scripte und deren Ausführung:

back-to-topAnleitung: Wie starte ich Powershell-Scripte
  • Zuerst speichert man den Code in einer Textdatei mit der Endung .ps1.
  • Wenn man zum ersten mal Powershell-Scripte ausführt, musst man einmalig vorher noch das Ausführen von Scripten im User-Account freischalten. Dazu öffnet man eine Powershell-Konsole und gibt dort den Befehl Set-ExecutionPolicy RemoteSigned -Force ein. Um diese Policy für alle User auf dem Rechner zu setzen muss man diesen Befehl in einer Powershell-Konsole mit Admin-Rechten starten. Noch ein Hinweis für 64-Bit-Systeme: Hier sollte sowohl für die 32bit und 64Bit Variante der Powershell die Policy in einer Admin-Konsole gesetzt werden: Set-ExecutionPolicy RemoteSigned -Force; start-job { Set-ExecutionPolicy RemoteSigned -Force } -RunAs32
  • Jetzt kann das Powershell-Script wie weiter unten erläutert in einer Powershell-Konsole oder aus einer CMD-Fenster heraus ausgeführt werden. Wer lieber mit der Maus arbeitet macht einen Rechtsklick auf die Script-Datei und wählt: Mit Powershell ausführen.
  • Alternativ lässt sich ein Script auch ohne das globale Ändern der ExecutionPolicy ausführen indem man die Policy als Parameter auf der Kommandozeile mitgibt:
powershell.exe -ExecutionPolicy RemoteSigned -File "C:\Pfad\Script.ps1"
back-to-topStarten eines Scriptes in einer Powershell-Konsole
Immer den kompletten Pfad zum Script angeben, und wenn er Leerzeichen beinhaltet in Anführungszeichen einschließen:
"C:\Pfad\script.ps1"
Liegt das Script im selben Verzeichnis in dem man sich gerade befindet, kann man es auch so abkürzen:
.\script.ps1
back-to-topStarten von PS-Scripten aus Batch und Kommandozeilen heraus:
Hier gibt es unterschiedliche Methoden, je nach Anforderungen gibt es hier einige Besonderheiten vor allem bei Leerzeichen in Pfaden zu beachten!
Der einfachste Aufruf sieht hier so aus:
powershell.exe -File "C:\Pfad\Script.ps1"
Wenn man dem Script Parameter übergeben möchte:
powershell.exe -File "C:\Pfad\Script.ps1" "Parameter 1" "Parameter 2"
Wenn man "benannte" Parameter übergeben möchte (die einfachen Hochkommas um den Scriptpfad werden benötigt wenn er Leerzeichen beinhaltet):
powershell.exe -command "&'C:\Pfad\Script.ps1' -par1 'Wert1' -par2 'Wert2'"
Man kann auch mehrere Scripte hintereinander ausführen lassen:
powershell.exe -command "&'C:\Pfad\Script1.ps1';&'C:\Pfad\Script2.ps1'"
Weitere Parameter zeigt einem ein powershell -? in einer Konsole an.
back-to-topStarten von PS-Scripten in der Aufgabenplanung (Taskplaner)
In der jeweiligen Aktion unter "Programm/Script" trägt man powershell.exe ein und unter "Argumente hinzufügen (optional)" trägt man wie oben geschrieben alles was hinter powershell.exe kommt ein - also z.B. -File "C:\Pfad\Script.ps1" "Parameter 1" "Parameter 2"
k.arkenau
k.arkenau 31.03.2015 um 08:30:22 Uhr
Goto Top
Moin,

ich habe das Script mal auf meine Bedürfnisse angepasst

powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\test' | ?{$_.PSIsContainer} | %{move-item -Path "$($_.Fullname)\*.pdf" -Destination $_.Directory.Parent.FullName; remove-Item $_.Fullname -Recurse -Force}}"

und es in ein bat Datei eingefügt.

Wenn den Job jetzt starte erhalte ich folgende Fehlermeldung:

Ausdrücke sind nur erstes Element einer Pipeline zulässig. Bei Zeile 1 Zeichen 162

Wo ist der Fehler?
colinardo
colinardo 31.03.2015 aktualisiert um 13:14:23 Uhr
Goto Top
Sorry, für die Verwendung in einer Zeile in Batch musste es noch etwas angepasst werden, s. korrigierten Code im letzten Post.

Grüße Uwe
k.arkenau
k.arkenau 31.03.2015 um 14:23:08 Uhr
Goto Top
Hallo Uwe,

ich habe diesen Code aus deinem letzte..äh...vorletzten Post genommen (und c:\rootordner durch c:\test ersetzt)

powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\test' | ?{$_.PSIsContainer} | %{$path=$_.Fullname + '*.\pdf'; move-item -Path $path -Destination $_.Parent.FullName; remove-Item $_.Fullname -Recurse -Force}}"

und in die batch eingefügt.

Ich bekomme aber wieder eine Fehlermeldung die da lautet: Ausdrücke sind nur als erstes Element einer Pipeline zulässig. Bei Zeile : 1 Zeichen: 167

Habe ich den falschen Code erwischt?
114757
114757 31.03.2015 aktualisiert um 14:26:36 Uhr
Goto Top
Moin k.arkenau,
geht hier testweise Problemlos, hast du irgendwelche Sonderzeichen in deinen Ordnernamen, wie z.B. ein Dollarzeichen oder Eckige Klammern () am Namensanfang ?

Gruß jodel32
k.arkenau
k.arkenau 31.03.2015 um 14:34:04 Uhr
Goto Top
Nö, eigentlich ist der Pfad, in dem die PDF Dateien liegen, ohne solche Zeichen:

C:\test\000\ELOPC04\Pdf\Archiv
114757
114757 31.03.2015 aktualisiert um 14:39:09 Uhr
Goto Top
Zitat von @k.arkenau:

Nö, eigentlich ist der Pfad, in dem die PDF Dateien liegen, ohne solche Zeichen:

C:\test\000\ELOPC04\Pdf\Archiv
öhm ...du weist aber schon das das obige Script nur die PDF Dateien aus der zweiten Ebene des Ordners nimmt ?!! Les dir den Thread noch mal genau durch ....
k.arkenau
k.arkenau 31.03.2015 um 14:47:55 Uhr
Goto Top
Ja, aber selbst wenn ich die Dateien in die zweite Ebene (c:\test\000) lege, bekomme ich diese Fehlermeldung.
114757
114757 31.03.2015 aktualisiert um 14:52:39 Uhr
Goto Top
Welche Powershell-Version benutzt du 2.0 / 3.0 ?

Zeigt dir ein $psversion in einer Powershell-Konsole an ...
k.arkenau
k.arkenau 31.03.2015 um 15:00:59 Uhr
Goto Top
Die Version ist 2.0
114757
114757 31.03.2015 um 15:03:37 Uhr
Goto Top
Dann mach mal ein Update ...
k.arkenau
k.arkenau 01.04.2015 um 15:17:00 Uhr
Goto Top
Moin,

so, ich habe auf 4.0 aktualisiert und den folgenden Batch Befehl ausgeführt:

powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\test' | ?{$_.PSIsContainer} | %{$path=$_.Fullname + '*.\pdf'; move-item -Path $path -Destination $_.Parent.FullName; remove-Item $_.Fullname -Recurse -Force}}"

Ergebnis:

Ausdrücke sind nur als erstes Element einer Pipeline zulässig.
+ CategoryInfo : ParserError: (face-smile , ParentContainsErrorRecordEx
ception
+ FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline

Sonst noch eine Idee?
colinardo
colinardo 01.04.2015 aktualisiert um 15:32:45 Uhr
Goto Top
'*.\pdf'
Schau mal ganz genau hin face-smile dann fällt dir dein Fehler auf ...

Grüße Uwe
k.arkenau
k.arkenau 01.04.2015 um 15:52:41 Uhr
Goto Top
Ok, Du meintest bestimmt den Backslash da, oder?

Skript ist jetzt:

powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\test' | ?{$_.PSIsContainer} | %{$path=$_.Fullname + '*.pdf'; move-item -Path $path -Destination $_.Parent.FullName; remove-Item $_.Fullname -Recurse -Force}}"

Meldung:

In Zeile:1 Zeichen:41

back-to-top&{gci 'C:\test' | ?{$_.PSIsContainer} | {$path=$_.Fullname + '*.pdf';

move-item ...

back-to-top~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~
Ausdrücke sind nur als erstes Element einer Pipeline zulässig.
+ CategoryInfo : ParserError: (face-smile , ParentContainsErrorRecordEx
ception
+ FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline
colinardo
colinardo 01.04.2015 aktualisiert um 16:01:39 Uhr
Goto Top
Ok, Du meintest bestimmt den Backslash da, oder?
ja aber du hast ihn jetzt entfernt, dabei sollte er an eine andere Position face-wink
'\*.pdf'

Mal den Kopf einschalten ... läuft wie gesagt einwandfrei!
k.arkenau
k.arkenau 01.04.2015 um 16:31:06 Uhr
Goto Top
Wie gesagt, bin absoluter Newbie was PowerShell angeht....von daher weiß ich auch nicht, wie PowerShell was interpretiert:

Skript ist jetzt:

powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\test' | ?{$_.PSIsContainer} | %{$path=$_.Fullname + '\*.pdf'; move-item -Path $path -Destination $_.Parent.FullName; remove-Item $_.Fullname -Recurse -Force}}"

Meldung:

In Zeile:1 Zeichen:41

back-to-top&{gci 'C:\test' | ?{$_.PSIsContainer} | {$path=$_.Fullname + '\*.pdf';

move-item ...

back-to-top~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~
Ausdrücke sind nur als erstes Element einer Pipeline zulässig.
+ CategoryInfo : ParserError: (face-smile , ParentContainsErrorRecordEx
ception
+ FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline
114757
114757 01.04.2015 aktualisiert um 16:52:29 Uhr
Goto Top
Das Script ist in Ordnung wie Colinardo sagt und hier läuft es ebenfalls, es muss also an deinen Ordnern oder Dateien liegen. Oder du wendest das ganz falsch in deiner Batch an was wir hier nicht sehen können.
Teste das ganz bitte erst mal nur in einer einzelnen Kommandozeile ohne Batchdatei...Vermutlich hast du deine Batch einfach in einem falschen Zeichensatz gespeichert.

Eine Übersicht deiner Ordnerstruktur und den Dateien wäre auch mal nicht schlecht, damit wir hier nicht dauernd rumraten müssen face-sad
k.arkenau
k.arkenau 01.04.2015 um 17:22:35 Uhr
Goto Top
Ok, von der Kommandozeile aus funktioniert er ganz wunderbar. Scheint also doch am Batch zu liegen, oder?

Der Ordner sieht so aus: c:\test
c:\test\Archiv\
Dieser enthält dann eine Menge PDF Dateien

Bis hierher schon mal vielen Dank für die Hilfe!
colinardo
colinardo 01.04.2015 aktualisiert um 18:01:53 Uhr
Goto Top
Scheint also doch am Batch zu liegen, oder?
Jup daran liegts, du musst das eine Prozentzeichen der Foreach-Schleife verdoppeln, der Fehler ist mir in deinen geposteten Codes vorhin nicht aufgefallen. Das hatte ich ganz zu Anfang ja angepasst.
Das Prozentzeichen ist in einer Batch "speziell" zu behandeln und wie bei einer Batch for-Schleife zu verdoppeln.
powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\test' | ?{$_.PSIsContainer} | %%{$path=$_.Fullname + '\*.pdf'; move-item -Path $path -Destination $_.Parent.FullName; remove-Item $_.Fullname -Recurse -Force}}"  
Damit sollte das nun abgehakt sein.

Grüße Uwe
k.arkenau
k.arkenau 07.04.2015 um 08:22:06 Uhr
Goto Top
Guten Morgen,

jetzt funktioniert das Script auch in der Batch.

Vielen Dank für Deine Hilfe!


Gruß

Karl-Heinz
k.arkenau
k.arkenau 07.04.2015 um 12:03:04 Uhr
Goto Top
Eine Frage noch:

Sollte der Fall auftreten, das ich noch tiefer in der Unterordnerstruktur wühlen müsste...wo müsste ich da im Skript ansetzen?
114757
114757 07.04.2015 um 12:24:34 Uhr
Goto Top
Zitat von @k.arkenau:
Sollte der Fall auftreten, das ich noch tiefer in der Unterordnerstruktur wühlen müsste...wo müsste ich da im
Skript ansetzen?
powershell -ExecutionPolicy ByPass -Command "&{gci 'C:\test\*.pdf' -recurse | move-item -Destination 'C:\Sammelordner'}"  
k.arkenau
k.arkenau 07.04.2015 um 13:01:51 Uhr
Goto Top
Danke nochmal, damit komme ich jetzt (und dann auch in Zukunft) klar.
colinardo
colinardo 07.04.2015 aktualisiert um 13:03:55 Uhr
Goto Top
Zitat von @k.arkenau:

Danke nochmal, damit komme ich jetzt (und dann auch in Zukunft) klar.
Und für weitere Powershell-Experimente empfehle ich erst mal folgende Lektüre:

Powershell Grundlagen- und Praxisvermittlung:
k.arkenau
k.arkenau 07.04.2015 um 13:52:14 Uhr
Goto Top
Und auch dafür vielen Dank. face-big-smile