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-Key: 265327

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

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

Member: Penny.Cilin
Penny.Cilin Mar 05, 2015 at 13:37:27 (UTC)
Goto Top
Hallo,

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


Gruss Penny.
Member: evolution
evolution Mar 05, 2015 at 18:32:00 (UTC)
Goto Top
Hab ich, aber nicht wirklich was gefunden, da ich nicht weiß nach was ich genau suchen muss
Member: colinardo
colinardo Mar 06, 2015, updated at Mar 30, 2015 at 14:17:32 (UTC)
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
Member: evolution
evolution Mar 08, 2015 at 20:16:43 (UTC)
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
Member: colinardo
colinardo Mar 08, 2015, updated at Mar 31, 2015 at 11:12:48 (UTC)
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
Member: k.arkenau
k.arkenau Mar 30, 2015 at 13:37:06 (UTC)
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?
Mitglied: 114757
114757 Mar 30, 2015 updated at 14:15:28 (UTC)
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
Member: k.arkenau
k.arkenau Mar 30, 2015 at 15:08:36 (UTC)
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?
Member: colinardo
colinardo Mar 30, 2015, updated at Apr 01, 2015 at 15:44:07 (UTC)
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"
Member: k.arkenau
k.arkenau Mar 31, 2015 at 06:30:22 (UTC)
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?
Member: colinardo
colinardo Mar 31, 2015 updated at 11:14:23 (UTC)
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
Member: k.arkenau
k.arkenau Mar 31, 2015 at 12:23:08 (UTC)
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?
Mitglied: 114757
114757 Mar 31, 2015 updated at 12:26:36 (UTC)
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
Member: k.arkenau
k.arkenau Mar 31, 2015 at 12:34:04 (UTC)
Goto Top
Nö, eigentlich ist der Pfad, in dem die PDF Dateien liegen, ohne solche Zeichen:

C:\test\000\ELOPC04\Pdf\Archiv
Mitglied: 114757
114757 Mar 31, 2015 updated at 12:39:09 (UTC)
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 ....
Member: k.arkenau
k.arkenau Mar 31, 2015 at 12:47:55 (UTC)
Goto Top
Ja, aber selbst wenn ich die Dateien in die zweite Ebene (c:\test\000) lege, bekomme ich diese Fehlermeldung.
Mitglied: 114757
114757 Mar 31, 2015 updated at 12:52:39 (UTC)
Goto Top
Welche Powershell-Version benutzt du 2.0 / 3.0 ?

Zeigt dir ein $psversion in einer Powershell-Konsole an ...
Member: k.arkenau
k.arkenau Mar 31, 2015 at 13:00:59 (UTC)
Goto Top
Die Version ist 2.0
Mitglied: 114757
114757 Mar 31, 2015 at 13:03:37 (UTC)
Goto Top
Dann mach mal ein Update ...
Member: k.arkenau
k.arkenau Apr 01, 2015 at 13:17:00 (UTC)
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?
Member: colinardo
colinardo Apr 01, 2015 updated at 13:32:45 (UTC)
Goto Top
'*.\pdf'
Schau mal ganz genau hin face-smile dann fällt dir dein Fehler auf ...

Grüße Uwe
Member: k.arkenau
k.arkenau Apr 01, 2015 at 13:52:41 (UTC)
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
Member: colinardo
colinardo Apr 01, 2015 updated at 14:01:39 (UTC)
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!
Member: k.arkenau
k.arkenau Apr 01, 2015 at 14:31:06 (UTC)
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
Mitglied: 114757
114757 Apr 01, 2015 updated at 14:52:29 (UTC)
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
Member: k.arkenau
k.arkenau Apr 01, 2015 at 15:22:35 (UTC)
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!
Member: colinardo
colinardo Apr 01, 2015 updated at 16:01:53 (UTC)
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
Member: k.arkenau
k.arkenau Apr 07, 2015 at 06:22:06 (UTC)
Goto Top
Guten Morgen,

jetzt funktioniert das Script auch in der Batch.

Vielen Dank für Deine Hilfe!


Gruß

Karl-Heinz
Member: k.arkenau
k.arkenau Apr 07, 2015 at 10:03:04 (UTC)
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?
Mitglied: 114757
114757 Apr 07, 2015 at 10:24:34 (UTC)
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'}"  
Member: k.arkenau
k.arkenau Apr 07, 2015 at 11:01:51 (UTC)
Goto Top
Danke nochmal, damit komme ich jetzt (und dann auch in Zukunft) klar.
Member: colinardo
colinardo Apr 07, 2015 updated at 11:03:55 (UTC)
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:
Member: k.arkenau
k.arkenau Apr 07, 2015 at 11:52:14 (UTC)
Goto Top
Und auch dafür vielen Dank. face-big-smile