trigger
Goto Top

Export eines Files mit Leerzeichen

Hallöle,

ich bin mit meinem Latein am Ende und hab keine Ahnung mehr, wonach ich jetzt noch suchen kann.

Ich habe ein Script geschrieben, was diverse Pfade aus einer Textdatei ausliest und dann in ein ZIP Archiv sichert. Neben den Pfaden, lasse ich auch nach bestimmten Dateiendungen suchen und lasse diese ebenfalls sichern. Das ganze funktioniert fasst gut.
Als Packprogramm kommt 7zip zum Einsatz. 7zip möchte aber die Pfadangaben ohne Laufwerksbuchstaben haben, da sonst die Pfade nicht mitgesichert werden.

Ein kleines Beispiel:
C:\Users\Trigger\*.txt soll gesichert werden. Dann muß ich angeben Users\Trigger\*.txt
7zip sucht jetzt nach allen *.txt Dateien und sichert sie mit vollen Pfad.

Gut habe ich mir gedacht, dann lässt du alles in eine Textzeile schreiben und entfernst die ersten drei Zeichen. Dazu habe ich ganz einfach meine Files.txt, in der meine Sicherungspfade stehen auslesen lassen und Zeile für Zeile suchen lassen. Die Suchergebnisse habe ich dann in eine path.tmp exportiert, welche ich dann durch
  :ProcessLine
      set "Line=%~1"   
      (echo %Line:~0,0%%Line:~3%)>>%BPATH%\path.txt 
dann bearbeiten lasse und das C:\ oder D:\ usw. löschen lasse. Als Ausgabe in der path.txt kommt dann der richtige Pfad, mit dem dann 7zip arbeiten kann.

Das man Pfade in Batch mit "" angibt, weiß ich. Aber wie ist es denn bei der ECHO Zeile? Wenn ich da "" Zeichen mitgebe, dann setzt sie diese dann an das erste Leerzeichen. Auch hier ein kleines Beispiel, wie die Ausgabe dann aussieht:

C:\Dokumente und Einstellungen soll gesichert werden und steht dann auch in der path.tmp richtig drin. nur nach dem Abschneiden bleibt nur noch Dokumente stehen. Wenn ich %Line:~0,0%%Line:~3% in "" setze, dann bekomme ich "Dokumente". Das gleiche passiert auch mit Dateinamen, die Leerzeichen haben.

Wie kann ich das Umgehen?

Ich poste mal das gesamte Script. Einiges werdet ihr schon von hier kennen. Das Forum war immer meine erste Anlaufstelle, wenn ich Probleme hatte und habe mich dann dem Wissen hier bedient. ;)

@echo off
setlocal
chcp 1252
if not exist %COMPUTERNAME%\logs mkdir %COMPUTERNAME%\logs

Rem Pfad angaben

set "syslw=C:\"  
set "server=\\bresrv02\Backup"  
set "epath=%CD%"  
set "bpath=%CD%\%COMPUTERNAME%"  
set "lpath=%CD%\%COMPUTERNAME%\logs\%DATE%-%COMPUTERNAME%.log"  
set "pex=%CD%\bin"  


REM Ab hier nichts mehr ändern


if exist %BPATH%\path.* del %BPATH%\path.*
set "path=%path%;%pex%"  
	echo ---- Alte Dateien werden entfernt > %lpath%
	echo. >> %lpath%
	echo %time% >> %lpath% && delage32 %bpath%* 2 /recurse >> %lpath%
	echo. >> %lpath%
	echo ----- >> %lpath%
  echo. >> %lpath%
cls
TITLE Client Profile Backup
  echo ********************************************************************
  echo *                                                                  *
  echo *    		      Profil wird gesichert                        *
  echo *                                                                  *
  echo ********************************************************************
  echo.
  echo Backup Verzeichnisse werden vorbereitet...
  echo ---- Text Dateien werden gesichert >> %lpath%
	echo. >> %lpath%
	CD /D %syslw%
  echo Daten werden gesichert. Dieser Vorgang kann ein paar Minuten dauern.  
	for /f "eol=# delims=" %%t in (%EPATH%\Files.txt) do dir /b /s %%t >> %BPATH%\path.tmp  
  for /f "usebackq delims=" %%l in (%BPATH%\path.tmp) do call :ProcessLine %%l   
  for /f "eol=# delims=" %%f in (%BPATH%\path.txt) do 7z.exe a %BPATH%\%DATE%-%COMPUTERNAME%.zip %%f >> %lpath%    
  del %BPATH%\path.*
	echo. >> %lpath%
	echo ----- >> %lpath%
	echo. >> %lpath%
	
	 @echo off %debug%
   setlocal
   set ll=V T R Q P O N M K J I W X Y Z L U S H G F E D
   for %%l in (%ll%) do (
   set LW=%%l
   mountvol %%l: /L >nul
   if errorlevel 1 (
      subst | findstr /B "%%l:" > nul  
      if errorlevel 1 (
         net use %%l: >nul  2>&1
         if errorlevel 1 goto gotone
        )
     )
   )
  echo Kein Laufwerksbuchstabe frei
  exit /b
  :gotone
	  net use %LW%: %SERVER% >NUL
	  if errorlevel=1 echo Fehler bei der Anbindung zum %SERVER% && goto :eof >> %lpath%
	  echo Verschiebe Daten auf %SERVER%
	  %LW%:
	  if not exist %COMPUTERNAME% mkdir %COMPUTERNAME%
	  if not exist logs mkdir logs
    copy /Y %BPATH%\%DATE%-%COMPUTERNAME%.zip %LW%:\%COMPUTERNAME%\ >>%lpath%
    copy /Y %lpath% %LW%:\logs\ >NUL
    net use %LW%: /del /yes >NUL
              
echo.
echo Sicherung abgeschlossen >>%lpath%


  :ProcessLine
      set "Line=%~1"   
      (echo %Line:~0,0%%Line:~3%)>>%BPATH%\path.txt

Eine Files.txt sieht dann in Etwa so aus:

######## Pfade
"C:\Users\Trigger\Documents"  


######## Dateien
"c:\Users\*.jpg"  

Ich hoffe, ihr könnt mir folgen. Wenn nicht, dann versuche ich es nochmal anders zu erklären. face-smile

Gruß
Trigger

Content-Key: 157372

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

Printed on: April 19, 2024 at 20:04 o'clock

Member: Biber
Biber Dec 21, 2010 at 15:09:52 (UTC)
Goto Top
Moin Trigger,

wenn du die Laufwerksangabe nicht brauchst in deiner Dateilisten-Datei, dann kannst du auch explizit die "Drive"-Angabe unterdrücken bei den FOR-Anweisungs-Variablen.

Beispiel am CMD-Prompt:
>for %i in ("C:\Users\Trigger\Documents", "Y:\Eigene Dateien\Download") do @echo "%~i" "%~npxi"  
"C:\Users\Trigger\Documents" "\Users\Trigger\Documents"  
"Y:\Eigene Dateien\Download" "\Eigene Dateien\Download"  

Was hier "rechts der Schlüsselwortes DO" herausfällt entspricht ja dem, was du du an den Block ":Processline" übergibst.
Genauer gesagt, du übergibst die unveränderte Variable "%%l", was wiederum gleichbedeutend wäre mit "%%~dpnxl" (%l mit Drive, Path, Name, eXtension).
Ohne den "Drive"-Anteil würde heißen "%%~pnxl" (%l mit Path, Name, eXtension).

Dann kommst du nicht ins Trudeln mit Substring-Abzählerei und Anführungszeichen.

Grüße
Biber
Member: Trigger
Trigger Dec 21, 2010 at 15:16:43 (UTC)
Goto Top
Biber, das ist ja mal Klasse. Leider habe ich das Script heute nicht mehr zur Verfügung, werde aber morgen gleich mal dran arbeiten.
Aber ich bin mir nicht ganz sicher, ob 7zip mit dem \ am Beginn der Zeile was anfangen kann. Ich teste es aber morgen mal durch.

Danke Dir vielmals!!

Gruß
Trigger
Member: Biber
Biber Dec 21, 2010 at 16:18:52 (UTC)
Goto Top
Moin Trigger,

eine andere Möglichkeit mit hilfe der Tokenzerlegung einer FOR/F-Anweisung wäre
>for /f "delims=\ tokens=1,*" %i in ("C:\Users\Trigger\Documents") do @echo "%~j"  
"Users\Trigger\Documents"  

(=17:11:26  D:\temp=)
>for /f "delims=\ tokens=1,*" %i in ("Y:\Eigene Dateien\Download") do @echo "%~j"  
"Eigene Dateien\Download"  
--> So wäre sowohl die Laufwerksangabe wie auch der erste Backslash weg.

Beide Varianten sind aus meiner Sicht les- und wartbarer als diese Substringarie und in beiden Fällen kannst du den Aufruf eines geCALLten Blocks ":Processline" einsparen, da du ja keine stattische Variable (mit SET gesetzte Variable, in deinem Schnipsel %Line%) mehr benötigst.

Grüße
Biber
Member: Trigger
Trigger Dec 22, 2010 at 08:38:24 (UTC)
Goto Top
Auf er Kommandozeile funktioniert das ganz gut, aber in einem Batchfile nicht. Ich muß aber gestehen, das ich die Line nicht ganz verstehe, was bei der Fehlersuche extrem suboptimal ist. Wenn ich die Zeile in einer Batch einbaue, dann kommt folgender Fehler:

Die folgende Verwendung des Pfadoperators zur Ersetzung eines Batchparameters
ist ungültig: %~j"


Geben Sie CALL /? oder FOR /? ein, um herauszufinden, welche Formate gültig
sind.
Member: Trigger
Trigger Dec 22, 2010 at 08:40:05 (UTC)
Goto Top
Ach gott... natürlich benötigt es ja zwei % Zeichen. face-smile
Member: Biber
Biber Dec 22, 2010 at 09:54:23 (UTC)
Goto Top
Ööööhmmmja, Trigger,

insgesamt lese ich aus deinem Feedback, dass du meine CMD-Prompt-Beispiele angetestet hast.

Allerdings kann ich nicht recht herauslesen, ob
  • du du dich denn für eine bestimmte Variante entschieden hast
  • dein Skript nun tut, was ein Skript halt tun soll
  • auch nach dem Lesen der FOR /?-Hilfe, auf die dich befreundete Praktikanten verwiesen haben, noch Fragen offen sind
  • deine vorläufig endgültige v002beta RC 5 nun künftigen BätchnovizInnen bereitgestellt wird
  • ob nun ein 6-Personen-WG-Mortadellafarbener Haken an den Thread kann.

Kannst du nochmal klären bitte?

Grüße
Biber
Member: Trigger
Trigger Dec 22, 2010 at 10:01:36 (UTC)
Goto Top
Warte noch ein wenig. Sowas will immer gut getestet werden.
Ich werde sehr, sehr sicher die praktikable Lösung hier einstellen. Immerhin möchte ich ja auch, das meine hier gewonnen Erfahrungen jemand anderen helfen können. ;)

Also, bitte noch einen Augenblick geduld. Ich mache das ja auch auf der Arbeit und habe dann noch den Alltag parallel zu bearbeiten.

Gruß
Trigger
Member: Trigger
Trigger Dec 22, 2010 at 11:05:06 (UTC)
Goto Top
Also...

ich habe mich dafür entschieden:

for /f "eol=# delims=" %%t in (%EPATH%\Files.txt) do dir /b /s %%t >> %BPATH%\path.tmp  
for /f "eol=# delims=\ tokens=1,*" %%i in (%BPATH%\path.tmp) do @echo "%%~j" >> %BPATH%\path.txt  
for /f "eol=# delims=" %%f in (%BPATH%\path.txt) do 7z.exe a %BPATH%\%DATE%-%COMPUTERNAME%.zip %%f  

Zeile 1 liest meine Files.txt aus, in der meine Sicherungspfade und Dateien drinstehen und schreibt eine temporäre Datei
Zeile 2 liest die temporäre Datei aus und schneidet das c:\ ab und schreibt es in die Path.txt
Zeile 3 7zip arbeitet die generierte Liste ab und sichert mit den vollständigen Pfaden

Biber, ich danke Dir vielmals für die kompetente Hilfe.

Gruß
Trigger