3. Win 10 power-archiver 2016
Einleitung
Eigentlich ist diese Abhandlung nicht nötig, weil es bereits unter Win
7 eine Batch zum kopieren von beliebigen Dateien gab. Es ist nur so ein
Übungsspiel, an dem wieder eine Reihe von Befehlen erklärt werden
können. Damit wird die alte Batch zur Archivierung abgelöst, die unter Win7, Win 8 und Win 10 natürlich weiterhin funktioniert.
Diese Datei besteht zu 100 % aus einer Batch und Sie müssen nur
beachten, dass der Einstiegspfad keine Leerzeichen oder Sonderzeichen
enthält:
c:\irgendein Ordner\lagederbatch
ist also nicht erlaubt, Genauso nicht auf oberster ebene eines
Laufwerks, also C:\archiv.bat funzt nicht. Ansonsten funktioniert alles.
Warum diese Ausnahmen? Mehrere Zeilen des Codes zerlegen einen Pfad und
ein Befehl braucht einen validen Pfad, die sind bei diesen Ausnahmen
nicht gegeben.
Die Batch bricht dann einfach ab, kommt nicht über die ersten Zeilen, also kein Problem...
Ach ja, die Unterordner dürfen wiederum natürlich auch doppelte Namen
enthalten!! Genauso dürfen die zu kopierenden Dateien Leerzeichen, ü,
ä,ö...und - enthalten: Der Powerarchiver hat einen hohen Wirkungsgrad...
Die Dateien werden in Jahreszahlen von 1990 bis 2016 gesammelt. Das ist
pure Wilkür und sie können die Jahreszahlen natürlich ändern, ich habe
das rot markiert. Die Dateien werden auch in der Namensgebung nicht
geändert und sind lediglich Kopien: Es wird nichts verändert!
Für Anfänger heißt das: einfach Code kopieren, eine Textdatei
erstellen, den blauen Code hereinkopieren, Batch mit Doppelklick
starten, die Dateiendung wie MP3, Doc, PDF oder ? eingeben und dann
werden die Dateien kopiert: In Ordnern mit Jahresnamen von 1990 an.
Die geläufigen Dateiendungen habe ich eben aufgeführt und wie gesagt:
Jpg, mp4 oder docx...ist alles erlaubt und bitte nicht andere Zusätze
wie den obligatorischen Punkt verwenden...
Für Amateuere erkläre ich dann Zeile für Zeile und das ist absoluter
Luxus, um selbst zu lernen wie die CMD denkt. Meine Beschreibungen sind
im Netz die ausführlichsten und dabei soll es bleiben: ich fing auch
mal mit einem dir-Befehl an...
Die Anwendung ist wieder auf eigene Gefahr und eigenes Risiko -:)
Für Anfänger:
Zur Erstellung einer Batch (*.bat) brauchen Sie nur bordeigene Mittel (Texteditor)
1. Als Vorraussetzung müssen Sie sich bekannte Dateiendungen anzeigen lassen: In beliebigen Ordner Registerkarte Ansicht: Dort Häkchen entfernen bei: Dateinamenerweiterungen.
2. Nun auf dem Desktop oder in einem Ordner mit rechter Maustaste auf freie Fläche drücken und neu - Textdokument auswählen.
3. Neues Textdokment öffnen (linker Doppelmausklick) und den o. a. Code durch kopieren über die Zwischenablage einfügen
4. Danach schließen. Abfrage mit Speichern mit ja beantworten.
5. Danach beliebigen Namen für die Archiv.bat vergeben - nur die Endung .bat ist vorgeschrieben - z. B- sortieren.bat, genial.bat...
Dann den u. a. Code kopieren:
set /p ende=Geben Sie die Dateiendung ohne Punkt ein!
set destination=%~dp0%
for /f "delims=" %%i in ('dir %destination%*.%ende% /s /b /a-d') do @echo %%i>>pfadliste.log
for /f "delims=" %%I in (pfadliste.log) do echo %%~sI>>pfad.txt
for /f "delims=" %%I in (pfadliste.log) do @echo %%~ntI>>datum.txt
for /f "delims= " %%i in (datum.txt) do echo %%i.>>ganzdate.txt
for /f "tokens=1,2,3,4 delims=." %%i in (ganzdate.txt) do echo %%k>>realdate.txt
FOR /F "tokens=*" %%A IN ('findstr /N .* "realdate.txt"') DO echo %%A^:>>tableone.log
FOR /F "tokens=*" %%A IN ('findstr /N .* "pfad.txt"') DO echo %%A^:>>tabletwo.log
FOR /F "tokens=1,* delims=:" %%i IN (tableone.log) DO echo %%j>tableone_%%i.log
FOR /F "tokens=1,* delims=:" %%i IN (tabletwo.log) DO echo %%j>tabletwo_%%i.log
set /a x=1
:further
for /f "delims=" %%a in (tableone_%x%.log) do for /f "delims=" %%i in (tabletwo_%x%.log) do echo %%i%%a>tablenew_%x%.log
set /a x=%x%+1
if exist *_%x%.log (goto further) else goto final
:final
set /a y=1
:last
for /f "TOKENS=*" %%a in ('dir tablenew_%y%.log /b') do type "%%a">>result.txt
set /a y=%y%+1
if exist tablenew_%y%.log (goto last) else goto nowend
:nowend
FOR /F "tokens=1,2,3 delims=:" %%i IN (result.txt) DO echo "%%i:%%j";%%k>>resulttwo.txt
del *.log
for /f "tokens=1,2 delims=;" %%i in (resulttwo.txt) do echo %%i>>%%j.log
set /a w=1989
:nchml
if %w% GTR 2017 goto zuende
set /a w=%w%+1
if exist %w%*.log (copy %w%*.log %w%.bak) else goto nchml
goto nchml
:zuende
dir *.bak /b >logliste.txt
for /f "tokens=1,2 delims=." %%i in (logliste.txt) do md %%i
set /a x=1989
:anfang
if %x% GTR 2017 goto ende
set /a x=%x%+1
if exist %x%.bak (goto weiter) Else goto anfang
:weiter
SET ziel=%destination%\%x%
FOR /F "usebackq delims=" %%a in (%x%.bak) DO COPY %%a "%ziel%\*.*"
goto anfang
:ende
del *.log
del test.html
del test.txt
del datum.txt
del ganzdate.txt
del pfad.txt
del realdate.txt
del result.txt
del resulttwo.txt
del logliste.txt
del *.bak
Die Batch sollte dann im obersten Verzeichnis liegen, da alle
Dateien mit der gesuchten Dateiendung in relativer Lage zur Batch im
selben Ordner und die Unterordner abgesucht und kopiert werden.
Danach wie gesagt Doppelklick auf die Batch. Dann die Dateiendung
eingeben, die kopiert werden soll, so bald sich das
Kommandozeilenfenster öffnet.
Es kann nichts passieren, da nur kopiert wird. Vorsicht, Log-Dateien
im selben Verzeichnis der Batch und *.bak werden zerstört. Die Lage der Batch sollte dann der oberste Ordner
sein, wo man kopieren will: alle Dateien im selben Verzeichnis und
sämtlichen Ordnern in den Unterverzeichnissen (Ordnern) mit derselben
Dateiendung werden nun kopiert in Unterordner mit der
Jahresbezeichnung: Der Dateiname der Kopie entspricht dem Original.
Damit verlasse ich die Anfängerebene und ab jetzt geht es für Amateure
weiter und ich beschreibe erstamal auf der Metaebene das Ziel:
Ich habe im Prinzip grundlegend versucht eine Dateiliste zu erschaffen,
wo in einer Zeile der Pfad und die Jahreszahl drinsteht. Diese Liste
exportiere ich dann in so viele Listen, wie es Dateien aus einem
bestimmten Jahr gibt.
Dann schaffe ich so viele Ordner mit denselben Namen von Jahreslisten
und kopiere diePfade in den Listen in die Zeitordner mit dem
Jahresnamen.
Das ganze sieht dann Zeile für Zeile beschrieben so aus:
set /p ende=Geben Sie die Dateiendung ohne Punkt ein!
set destination=%~dp0%
Die ersten beiden Zeilen sind erstmal von fast derselben Machart: In
der ersten Zeile generiere ich eine Abfrage für die Variable ende, womit ich dann die Dateiendung meine: Der Text nach dem Gleichheitszeichen wird dem User angezeigt - set /p ist dazu der Befehl.
Damit ist die Dateiendung in der Variable %ende% (bei Batsch immer zwei Prozentzeichen...)
Die zweite Zeile ist nur die Variable für den Standort (Dateipfad) der
Batch. Da brauchen sie nichts einzugeben! Wir haben also die
Dateiendung nach Eingabe durch den User und kennen dank der fest
geschriebenen Wendung %~dp0% den Dateipfad zur Batch wie z. B. c:\irgendeinordner...
Die nächsten Zeilen sind jetzt für viele Batchschreiber ein Krampf, weil der for-Befehl für viele eine Hürde ist:
for /f "delims=" %%i in ('dir %destination%*.%ende% /s /b /a-d') do @echo %%i>>pfadliste.log
for /f "delims=" %%I in (pfadliste.log) do echo %%~sI>>pfad.txt
for /f "delims=" %%I in (pfadliste.log) do @echo %%~ntI>>datum.txt
for /f "delims= " %%i in (datum.txt) do echo %%i.>>ganzdate.txt
for /f "tokens=1,2,3,4 delims=." %%i in (ganzdate.txt) do echo %%k>>realdate.txt
Ich will erstmal ein Dokument generieren (pfadliste.log), welches sämtliche ('dir %destination%*.%ende% /s /b /a-d') mp3 Dateien z. B. beinhaltet, die in Pfaden unterhalb und neben der Batch liegen (('dir %destination%*.%ende% /s /b /a-d')) . Da stehen also sämtliche Pfade drin.
Wenn sie wollen ist das eine Liste ohne irgendwelche Seperatoren ("delims="),
wo untereinander der komplette Pfad eingetragen wird, für jede Datei
eine Zeile und diese Liste wird übergeben, Zeile für Zeile (do @echo %%i) und deshalb auch (>>), weil mit einer Ausgabe immer wieder in Pfadliste.log destruktiv überschrieben wird.
Das ist doch jetzt toll und wozu müssen wir dann im zweiten for Befehl die Liste ((pfadliste.log)) noch einmal konvertieren (pfad.txt)?
Nun, %%~sI
bedeutet, dass die Pfade ein Stück konvertiert werden und das
ist leider notwendig, weil ich nun einmal weiß, dass ich später
Probleme mit Dateinamen bekomme, die nicht im Dos-Format vorliegen.
Denn ich will jetzt einmal nur Textdokumente verwenden und später mit
Jahreszahl kombinieren und kopieren - das geht nicht ohne Bereinigung.
Früher machte ich das mit einer extra Batch..., dann ist es doch besser im Vorfeld Probleme zu lösen.
Deshalb sagt die zweite Reihe auch nur übersetzt: Nimm die untereinanderstehenden Dateipfade aus der Liste von pfadliste.log und erstelle ein neues Dokument pfad.txt
Damit sind wir schon bei der dritten for Zeile:
for /f "delims=" %%I in (pfadliste.log) do @echo %%~ntI>>datum.txt
Richtig, das sieht durch das @echo
erstmal anders aus, heißt aber nur, dass außer dem Dospfad eben noch
die Angaben zu der Datei reflexiv ausgegeben werden, vielleicht einmal
die Visualisierung, wie so eine Zeile in test.html aussieht: C:\Users\Snappy\Desktop\test\tet\SHKKSP~1.MP3 12.09.2015 10:59 SHKKSP~1
Für diese dämliche Ausgabeform kann ich nichts, deshalb habe ich erstmal mehraufwand.
Jetzt müssten sie verstehen, warum eine vierte For Schleife nötig wird:
for /f "delims= " %%i in (datum.txt) do echo %%i.>>ganzdate.txt
Ich will jetzt den Pfad mit Titel und das Datum 2015 selektieren.
C:\Users\Snappy\Desktop\test\tet\SHKKSP~1.MP3 . 12.09.2015.
Richtig, da ist noch ein kleiner Trick bei: Ich gebe einen weiteren
Punkt ein, damit ich durchgängig einen Punkt als Separator habe: Das
ist für die nächste for-Schleife unabdingbar...
Das ist immer noch dämlich, weil ich nach Jahren sortieren will und deshalb gleich wieder eine for-Stapelverarbeitung:
for /f "tokens=1,2,3,4 delims=." %%i in (ganzdate.txt) do echo %%k>>realdate.txt
Also extrahiere ich nun das Datum allein in die Datei realdate,
wodurch da eine 2015 im Beispiel entsteht und danach eine fast
unsichtbare Beschränkung, die wie ein Leerzeichen aussieht, aber ein AD
AO - Schalter ist und die man mit Batchmitteln nicht so ohne weiteres
wegbekommt. Ist zum Kotzen und muss später ausgeglichen werden:
Indes fügt der folgende Code nur das Datum und den Pfad wieder zusammen:
FOR /F "tokens=*" %%A IN ('findstr /N .* "realdate.txt"') DO echo %%A^:>>tableone.log
FOR /F "tokens=*" %%A IN ('findstr /N .* "pfad.txt"') DO echo %%A^:>>tabletwo.log
FOR /F "tokens=1,* delims=:" %%i IN (tableone.log) DO echo %%j>tableone_%%i.log
FOR /F "tokens=1,* delims=:" %%i IN (tabletwo.log) DO echo %%j>tabletwo_%%i.log
set /a x=1
:further
for /f "delims=" %%a in (tableone_%x%.log) do for /f "delims=" %%i in (tabletwo_%x%.log) do echo %%i%%a>tablenew_%x%.log
set /a x=%x%+1
if exist *_%x%.log (goto further) else goto final
:final
set /a y=1
:last
for /f "TOKENS=*" %%a in ('dir tablenew_%y%.log /b') do type "%%a">>result.txt
set /a y=%y%+1
if exist tablenew_%y%.log (goto last) else goto nowend
:nowend
FOR /F "tokens=1,2,3 delims=:" %%i IN (result.txt) DO echo "%%i:%%j";%%k>>resulttwo.txt
del *.log
Diese Code wurde von mir zur Zusammenführung von Tabellen beschrieben und deshalbt verweise ich auf die Abhandlung über CSV.
Im Dokument resulttwo.txt sieht dann die Datei auf eine Zeile in einem Beispiel reduziert so aus:
"C:\Users\Snappy\Desktop\test\2015\DUSTIN~1.MP3";2015
Wichtig: Im letzten For-Befehl wurden sämtliche Reihen auf diese Bauart
getrimmt, da stehen nun gleichartige Zeilen mit verschiedenen Daten
drin - je nachdem aus welchem Jahr diese Datei stammt.
Die nächste Einheit schafft Bak-Dokumente, die die Jahreszahl als
Überschrift und den Dateipfad in Anführungszeichen beinhalten. Das ist
eine reine Routine zur Fehlerbereinigung der CMD, die hinter dem Datum
ein unsichtbares Steuerzeichen mit sich rumführt und deshalb mache ich
an diesem Punk aus 2015 .log eine 2015.bak ohne unsichtbares
steuerzeichen-:)
for /f "tokens=1,2 delims=;" %%i in (resulttwo.txt) do echo %%i>>%%j.log
set /a w=1989
:nchml
if %w% GTR 2017 goto zuende
set /a w=%w%+1
if exist %w%*.log (copy %w%*.log %w%.bak) else goto nchml
goto nchml
:zuende
Ich setze dazu eine Variable w auf 1989 und lasse diese bei jedem Schleifendurchgang mit einer 1 addieren und wenn die Zahl größer als 2017 ist (
if %w% GTR 2017 goto zuende), dann beendet sich die Schleife.
Jedes Jahr wird also geprüft, ob ein Dokument vorliegt (%w%*.log = z. B. 2015 .log) Liegt ein solches Dokument vor, dann kopiere ich dieses Mistleerzeichen heraus und schaffe ein (%w%.bak =2015.log) ein Bak-Dokument: Deshalb der * als Wildcard.
Dasselbe mit den Pfaden von MP3 Dateien aus dem Jahr 2013, 2014, eben
den Pfad jeder Datei als Jahresdokument und damit ist die erste Hälfte
der Arbiet erledigt.
dir *.bak /b >logliste.txt
for /f "tokens=1,2 delims=." %%i in (logliste.txt) do md %%i
set /a x=1989
:anfang
if %x% GTR 2017 goto ende
set /a x=%x%+1
if exist %x%.bak (goto weiter) Else goto anfang
:weiter
SET ziel=%destination%\%x%
FOR /F "usebackq delims=" %%a in (%x%.bak) DO COPY %%a "%ziel%\*.*"
goto anfang
:ende
Die Bak-Dokumente werdennamentlich in einem Loglisten-Dokument zusammen gefasst, um die dazugehörigen Ordner zu erstellen,
da steht also
2011.bak
2015.bak
usw. drin, wenn es in diesen Jahren ein zu kopierendes E lement gab.
for /f "tokens=1,2 delims=." %%i in (logliste.txt) do md %%i
erschafft dann beim o. a. Beispiel die Ordner 2011 und 2015, weil md
eben der Befehl ist der auf %%i, also dann 2011 wäre und delim ist der
Punkt.
Dann existieren also Ordner mit Jahreszahlen und die zugehörigen
Bak-Doument, in denen der zu kopierende Pfad in Anführungszeichen
steht.
SET ziel=%destination%\%x%
FOR /F "usebackq delims=" %%a in (%x%.bak) DO COPY %%a "%ziel%\*.*"
Das ist nun die eigentliche Kopieraktion: Der Pfad zum Ziel wird über
eine weitere Variable x geliefert, die wieder von 1990 bis 2018
durchläuft.
(Gibt es ein Bak), welches vorher geprüft wurde, dann gibt es zu 100 % auch den Ordner im Ziel)
Wichtig ist die Formel "usebackq delims=" , denn die bewirkt, dass ein Dateipfad in Anführungszeichen als solcher im For-Befehl interpretiert wird.
Vereinfecht gesagt: Es wird nur sonst die Hälfte vom Pfad angezeigt
oder gar nichts. Auch das %%a in Anführungszeichen nach Copy ist
tödlich.
Der Copy Befehl in For-Schleifen ist eine Herausforderung und auch Semiprofis werden diese Codezeile zu schätzen wissen...
Die zwei Sterne im For-Befehl sind wiederum nur Wildcards, damit die
Datei beim richtigen Pfad ankommt: Das ist eine stabile Konstruktion,
aber mit eine der schwersten Zeilen in dieser Batch: Wenn sie die unter
dreiStunden so hinbekommen, dann sind sie cleverer als der Autor, der
wirklich eine Menge Variationen versuchte.
Impressum