biber
Goto Top

Workshop Batch for Runaways - Part II - Ein bisschen Handwerkszeug

Fortsetzung vom Workshop Batch for Runaways - Part I - Beispiel FindLongPath.Bat Bedenklich lange Pfade finden
To be cont'd....

Weiter gehts mit dem kleinen Batch-for-Runaways-Workshop.
Ich werde den Aufbau vom Teil 1 beibehalten: ein paar Grundlagen, viel Prosa und das Posten von ein oder zwei im Admin-Alltag verwendbaren Utilities.
Und natürlich noch ein paar erläuternde Worte zu dem Bätchelchen "FindLongPath.bat" vom letzten Mal.
Fangen wir mal auf dem Acker an, bei den Grundlagen, wer will zumindest..
Vollzieht folgenden Batch in Gedanken nach...
::---- snipp Intro-Workshop2.bat
@echo off
Set /p Leser="Deine Kenntnisse an Batch-Know-How? K=Klein, M= Mittel G=Groß? "   
If /i "%Leser%"=="K" (set Leser=Newbie) && Rem if /i bedeutet ohne Klein/Großschreibung vergleichen  
If /i "%Leser%"=="M" set Leser=Advanced   
If /i "%Leser%"=="G" set Leser=Guru  
for %i in (Newbie Advanced Guru) do If (%Leser%)==(%i) goto %Leser%Stuff 
Rem Benutzer hat nur ENTER oder weder K noch M noch G gedrückt..naja, dann nicht
(Echo Danke fürs Reinschauen!) & goto :eof
::------ snapp Intro-Workshop2.bat 
:NewbieStuff
CMD-Befehle vom Prompt und in der Batch-Datei: ein paar Unterschiede..
Die CMD.exe ist ein Befehls-Interpreter. Das heißt, Zeile für Zeile wird nacheinander abgearbeitet, Syntaxfehler also auch erst dann "gemerkt", wenn versucht wird, eine Zeile auszuführen. Und der CMD-Interpreter bietet von Haus aus
- NICHT die Möglichkeit eines Syntaxchecks VOR der Ausführung,
- NICHT die Möglichkeit, ein Batchprogramm Schritt für Schritt ablaufen zu lassen
- NICHT die Möglichkeit, Variableninhalte zwischendurch anzuzeigen
Warum erzähl ich solche Trivialitäten? Damit klar wird, wieviel Zeit man/frau sparen kann, wenn ein paar Tipp-/Denk-/Syntaxfehler gar nicht erst gemacht werden... und dazu muss eben einmal der geneigte Leser verstehen, was der CMD-Interpreter versteht und was nicht. Oder, um mal ein Wortspiel zu versuchen, ich darf dem Interpreter keinen Interpretationsspielraum lassen.

Mal das wichtigste Handwerkszeug:

a) Variablen ansprechen: in %-Zeichen setzen (echo %username%).
Weder CMD-Befehle noch Variablennamen sind Case-sensitiv (Ausnahme FOR..IN..DO-Zähl-Variablen).
Vollkommen gleichbedeutend sind also "echo %username%" und "Echo %UserName%" und ECHO %USERNAME%"

b) Zählvariablen in FOR..IN..DO-Schleifen: ein %-Zeichen vom Prompt aus (%i), zwei im Batch (%%i). Zählvariablen sind Case-sensitiv ( %%a ist ungleich %%A ).

c) ob eine Variable definiert ist oder nicht, läßt sich (Achtung, dürfte einigen neu sein) sowohl vom Prompt aus wie im Batch mit "if defined Variable" feststellen.
Fällt unter die Rubrik kleine Kuriositäten. (Beispiel mit undefinierter Variable test123)
[im Batch] if [%Test123%]== (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis) Test123 ist nicht definiert.
[am Prompt]>if [%Test123%]== (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis)Test123 hat Wert %test123% *nanu? Kopfkratz*
[Prompt und Batch] if NOT defined test123 (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis)"Test123" ist nicht definiert

d) Für Variablen gibt es auch eine (abschreckend aussehende) Substringfunktion (echo %path:~0,20% liefert die ersten zwanzig Zeichen der Variablen %path% - von Zeichen 0 in der Länge 20) und auch eine Suchen/Ersetzen Funktion (set test=Müller; set test=%test:ü=ue% Ergebnis: test=Mueller)

e) Bei Vergleichen mit den Operatoren (==, NEQ, GTR,...) muss immer auf beiden Seiten des Operatoren etwas stehen, sonst gibt es einen "Syntaxfehler". Zu recht natürlich.
Also im Batch nie prüfen
if %username%==Fritz goto :FritzensStuff ....sondern
if (%username%)==(Fritz) goto :FritzensStuff ..oder...if [%username%]==[Fritz] goto :FritzensStuff
Warum? Wenn %username% nicht definiert ist, wird die erste Variante aufgelöst zu
"if ==Fritz goto :FritzensStuff" und das liefert...ja genau...*gg
Außerdem könnte ich die If-Test123-Zeile oben sonst auch gar nicht formulieren: if [%Test123%]== goto... ohne Anfü-oder -Zeichen.
Das könnte nicht mal ich interpretieren, geschweige denn so ein doofer M$-Interpreter *gg

f) das Ausgabe-Umleiten... ist oft sinnvoll in Batchdateien. Viele Befehle liefern ja eine Rückmeldung auf den Bildschirm, die ich aber im Batch gar nicht lesen oder an ein anderes Programm lieber eine Protokoll-Datei übergeben will. Eine Ausgabe kann ich also zum Beispiel
- in eine Datei umleiten mit den Zeichen ">" (umleiten, Datei neu anlegen) und ">>" (falls Ziel-Datei vorhanden, anhängen),
- eine der häufigsten Batch-Umleitungen ist das Umleiten ins Nirwana ) ">nul" ."dir >nul" bedeutet also: Kommando "Dir" ausführen und den Output nicht anzeigen. Nicht sinnvoll? Abwarten...
- mit "|" den Output einer Anweisung als Input für die nächste Anweisung verwenden oder
- mit "<" aus einer Quelle lesen
Weitgehend unbemerkt bleibt allerdings, dass Bildschirm-Rückmeldungen durchaus differenziert zurückgegeben werden, nämlich als "normale" Meldungen auf den Bildschirm alias STDOUT (oder 1) und als Fehlermeldungen auf STDERR (oder 2),
Beispiel gefällig?
>dir *.lo?
 Verzeichnis von D:13.01.2005  03:59                4.793 resolve.log
               1 Datei(en)          4.793 Bytes
               0 Verzeichnis(se),  12.667.240.448 Bytes frei
>dir /b *.lo?
resolve.log
>dir /b *.log >nul
(keine Rückmeldung auf dem Bildschirm)
>dir /b *.lod
Datei nicht gefunden
>dir /b *.lod>nul
Datei nicht gefunden
>dir /b *.lod>nul 2>nul 
Wie zu sehen ist, ist die Meldung "Datei nicht gefunden" eine Fehlermeldung (auf STDERR oder 2), die auch zu sehen ist, wenn ich die normale Bildschirmausgabe unterdrücke. Die muss/kann ich gesondert umleiten.
g) die Prüfung eines ERRORLEVEL ist oft nützlich, sollte man/frau kennen beim Bätche-Bauen.
Kurzgefasst: (fast) jedes Programm/jede CMD-Anweisung gibt einen numerischen ERRORLEVEL-Wert zurück, aus dem sich Erfolg (=0) oder Fehler (1-255) ablesen lassen. Und je nach Erfolg oder Fehler eines Befehls können natürlich unterschiedliche Aktionen in einem Batch folgen.
Beispiel: ">dir /b *.lod>nul 2>nul" liefert ein Errorlevel größer 0, weil, ja ein Fehler aufgetreten ist.
Ein "echo Errorlevel vom letzten Befehl ist: %ERRORLEVEL%" liefert "Errorlevel vom letzten Befehl ist 1"

  • A & B .....führe erst A aus, dann B ..also in jedem Fall beide Anweisungen
(dir /b *.lod>nul 2>nul) & echo Errorlevel vom letzten Befehl ist: %ERRORLEVEL%
  • A && B Führe erst A aus, nur wenn kein Fehler, dann auch B
(dir /b *.lod>nul 2>nul) && echo Dateien *.lod sind vorhanden!
B ...führe A aus, nur wenn Fehler auftrete, führe B aus(dir /b *.lod>nul 2>nul)

i) wenn ich im Batch indirekt andere Anweisungen ausführen lasse, muss ich deren Parameter/Umleitungen unter Umständen im Batch mit ^ "maskieren" (Beispiel folgt weiter unten...beim P.S.)
j) das Allerwichtigste (nicht hauen jetzt): zu jedem CMD-Befehl gibt es Hilfe vom CMD-Prompt aus (ECHO /? oder FOR /? oder SET /? oder einfach HELP for alles)

Zurück zur Praxis.Wir fangen mal mit am CMD-Prompt an, da, wo wir letztes Mal aufgehört haben, bei SET, %variablen%, ECHO. FOR... IN ..DO". Alle Zeilen, die mit einem ">" anfangen, sollen eine Eingabe am CMD-Prompt bedeuten. Ach ja, wer noch den Standardprompt hat, sollte den mal anpassen zum besseren Arbeiten, passt zum Thema Variablen.
Ein bisschen Platz zum Eintippen sollte schon da sein. Wenn der Eingabeprompt schon so ähnlich aussieht wie "D:\Dokumente und Einstellungen\DerBiberAusBremen>" macht es keinen Spaß, etwas einzutippen. Schaffen wir uns Platz ohne Informationsverlust.

:AdvancedStuff

<Ausgangssituation
..gibt gleich eine kleine Aufgabe dazu.
Abfrage der Variablen "prompt"
> set prompt
Die Umgebungsvariable "prompt" ist nicht definiert  (die Antwort vom CMD-Interpreter bei Newbies)  
prompt=$p$g$ (die Antwort vom CMD-Interpreter bei allen, die schon einen eigenen Prompt definiert haben)
Als Variable ansprechen:
>echo %prompt%
%prompt% (die Antwort bei Newbies) bzw. $p$g (die Antwort bei anderen)
Alles klar? Die Variable %prompt% kann definert sein oder auch nicht, bevor der erste Minibatch startet.
Kleine Workshop-HausAufgabe
Ich möchte gern einen zweizeiligen Prompt haben, dort, wo ich tippe, soll nur ein ">"-Zeichen am Beginn der Zeile stehen. Was bisher im Prompt stand (LW/Pfad etc) soll in die Zeile darüber.
Tipp1: siehe bei ">Prompt /?" .. eine neue Zeile beginnen mit "$_", ein Größer-Zeichen in den Prompt einbauen mit "$g" oder (auf Deutsch) ich möchte, dass die Variable %prompt% mit "$_$g" endet.
Ach ja, aber nur, wenn der %prompt% bisher noch keinen Zeilenumbruch beeinhaltet. Sollte im Prompt schon ein Zeilenunbruch enthalten sein, diesen durch ein Leerzeichen ersetzen.
Tipp2: sollte die Variable %Prompt& noch nicht definert sein, wird sie von Windows als "$p$g" angenommen.
Macht doch mal mit dem gelesenen ( vor allem die Punkte b) und c)) einen ChangePrompt.bat, Editor aufrufen, eintippen, speichern, und starten. Bin gespannt auf die Lösungen.

Für heute soll reichen: Die Variable %prompt% ändern auf zweizeilig geht mit $_

Wer das dauerhaft bei jedem Öffnen eines CMD-Prompts haben möchte, muss eine Benutzervariable Prompt definieren unter Start->Einstellungen, System->Erweitert->Umgebungsvariablen

:GuruStuff
Okay, ich versuch mal ein paar Möglichkeiten auzuzeigen, die beim Rumbätcheln so möglich sind.
Ich wollte ja ein paar Worte zu dem FindLongPath.bat aus dem Teil 1 des kleinen Workshops sagen.
Dazu wäre es sinnvoll, diesen Batch nochmal hier zu posten, aber mit Zeilennummern. Ist einfacher.
Hmm..soll ich sowas zu Fuß machen, Copy & Paste und dann Zeilennummern eingeben? Wer bin ich denn?
Das lass ich mal ein 20-Zeilen-Bätchelchen machen, dieses hier:
::-----snipp NumberMe.bat---
@echo off & SETLOCAL EnableDelayedExpansion
::NumberMe.bat ... eine Textdatei mit ZeilenNummern versehen. 
::Version 0.03 Placed into the Public Domain by Biber3@hotmail.de 15.08.2004
::Syntax: %0 InDatei [OutDatei] [/n:Anzahl Stellen der Zeilennummerierung, Default 2]
:: wenn Outdatei nicht angeben wird, dann Ausgabe nur auf Bildschirm/Con:
::----die leidigen Parameter-Prüfungen folgen...*seufz*
IF "%1"=="" (echo Syntaxfehler: %0 InDatei [OutDatei] [/n:Breite Num.]) & (md 2>nul) & goto :eof  
IF Not exist "%1" (echo Fehler %0: InDatei "%1" nicht gefunden.) & (md 2>nul) & goto :eof  
For %%i in ( con: /n:2 %2 %3) Do call :SetParameter %%i
IF NOT [%pOutput%]==[con:] if exist "%pOutput%" del "%pOutput%"  
set /a line=10000
For /F "delims=" %%i in (%1) do (  
      set /a line=!line!+1
      echo !line:~-%pN%! %%i >>%pOutput% )
goto :eof
:SetParameter
set pX=%1
if /i "%pX:~0,3%"=="/n:" (if "%pX:~3%" GTR "0" (set /a pN=%pX:~3%))  ELSE set pOutput=%1  
goto :eof
:: -----snapp NumberMe.bat---
der beim Aufruf von "NumberMe NumberMe.bat" sich selbst so aufbereitet:
01 @echo off & SETLOCAL EnableDelayedExpansion  
02 ::NumberMe.bat ... eine Textdatei mit ZeilenNummern versehen.   
03 ::Version 0.03 Placed into the Public Domain by Biber3@hotmail.de 15.08.2004  
04 ::Syntax: %0 InDatei [OutDatei] [/n:Anzahl Stellen der Zeilennummerierung, Default 2]  
05 :: wenn Outdatei nicht angeben wird, dann Ausgabe nur auf Bildschirm/Con:  
06 ::----die leidigen Parameter-Prfungen folgen...*seufz*  
07 IF "%1"=="" (echo Syntaxfehler: %0 InDatei [OutDatei] [/n:Breite Num.]) & (md 2>nul) & goto :eof    
08 IF Not exist "%1" (echo Fehler %0: InDatei "%1" nicht gefunden.) & (md 2>nul) & goto :eof    
09 For %%i in ( con: /n:2 %2 %3) Do call :SetParameter %%i  
10 IF NOT [%pOutput%]==[con:] if exist "%pOutput%" del "%pOutput%"    
11 set /a line=10000  
12 For /F "delims=" %%i in (%1) do (    
13       set /a line=10013+1  
14       echo line:~-%pN% %%i >>%pOutput% )  
15 goto :eof  
16 :SetParameter  
17 set pX=%1  
18 if /i "%pX:~0,3%"=="/n:" (if "%pX:~3%" GTR "0" (set /a pN=%pX:~3%))  ELSE set pOutput=%1    
19 goto :eof 
Nun kann ich ziemlich einfach Kommentare schreiben. Mach ich auch.
ad 02: Zwei Befehle in einer Zeile mit & hatte ich schon erwähnt, SETLOCAL EnableDelayedExpansion noch nicht. Siehe dazu bitte die Hilfe bei Setlocal /?
ad 06 Da schwächelt mein Batch...Umlaute gehen verloren. Hätte ich euch auch verschweigen können. Mach ich in der nächsten Version weg. *gg
ad 07 Parameter fehlt? Dann die richtige Syntax anzeigen. Ist guter Stil IMHO.
Fehlermeldung bei Aufruf ">NumberMe" wird expandiert zu: "Syntaxfehler: NumberMe InDatei [OutDatei] [/n:Breite Num.]"
ad 08 Angegebene Datei nicht gefunden. Sollte der Benutzer wissen. Fehlermeldung bei Eingabe ">NumberMe num" wird expandiert zu "Fehler NumberMe: InDatei "num" nicht gefunden."
ad 09 Hier setze ich meine beiden Variablen pOutput und pN erst auf Befault, dann auf das, was der Anwender will.Und zwar mit "call SetParameter %1". Ein "call :xx" wird ausgefüht bis zu einem "goto :eof und kehrt dann zurück. Schaun wir mal, was da passiert.
ad 16 Da springt der "Call" also hin
ad 17 den Parameter, z.b. "con:" oder "/n:2" mal eben zwischenspeichern in Variable pX
ad 18 Prüfen, ob die ersten 3 Stellen="/n" sind, wenn ja und ein numWert folgt, setzen von pN als Zahl bzw.
wenn Nicht die ersten 3 Stellen ="/n" sind und ein numWert folgt, setzen von pOutputmit diesem Parameter
ad 19 Entspricht einem "Return" ..zurück zu Zeile 09
ad 10 Falls die eine Outputdatei angegeben ist und eine alte Version existiert, diese löschen. Aber Bildschirm nich löschen *gg
ad 11 Die Variable "line" brauche ich, um Zeilennummern anzuzeigen. bzw die letzten Stellen pN Stellen davon. Okay, okay, ich gehe in der Praxis davon aus, das nur 2 bis 4 Stellen realistisch sind. Wer damit Texte nit mehr als 9999 Zeilen "nummerieren" will, sollte noch ein paar Nullen dranhängen.
ad 12-14 eine FOR.. IN ..DO -Schleife über mehrere Zeilen. Geht, wenn es geklammert wird.
ad 13 13 ist eine Unglückszahl.14 auch.Hier hat der Aufruf von "NumberMe NumberMe.bat dazu geführt, dass der CMD-Interpreter den Text in der Inputdatei teilweise auflöst,
Eine der lustigen Kuriosiäten des CMD-Interpreters, die man nur bemerkt, wenn man/frau mal Batchdateien mit mehr als 10 Zeilen zu schreiben versucht. Ein Seiteneffekt dieser vom M$ halbherzig implementierten "SETLOCAL EnableDelayedExpansion"-Mimik ist, das alles, was zwischen zwei Anführungszeichen steht, als sofort aufzulösende Variable abgesehen wird. Seiteneffekt im richtigen Leben:
>Type Ausrufezeichen.txt
Microsoft, ihr könnt es !nicht programmieren. lasst mich das machen!am Besten.
Super! Diesen Text versucht der CMD-Interpreter als Variable aufzulösen!
D:\temp>
>NumberMe Ausrufezeichen.txt
01 Microsoft, ihr könnt es am Besten.
02 Super
Na ja, an solche solche Sachen wie CMD-Interpreter werde bei M$ sicher auch nur Praktikanten gesetzt.
Variable %line% wird hier auflöst wird zur Zahl 10013...Shit happens. Eigentlich steht hier "set /a line=!line!+1" .Was bedeutet, zähle die %line% um 1 hoch und mach das SOFORT. Grund: der CMD-Interpreter hat ja schon die ganze FOR-Anweisung gelesen und überall schon %line% durch den Wert von %line% ersetzt. Ich will aber den Wert von %line innerhalb der Anweisung verändern.
ad 14 Eigentliche Zeile: "echo !line:~-%pN%! %%i >>%pOutput%". Siehe ad 13). Okay, den meisten von Euch wellen sich die Fussnägel bei so einer Zeile, aber ich kanns erklären..*gg. Was ich hier will (und auch tue) ist, eine Zeile der Form "nn TextblablaBlubb" in eine Datei %pOutput" anzuhängen. Der "TextblablaBlubb" steht in %%i. Und die Zeilennummer bilde ich aus den letzten Stellen der %line%-Variablen, die in dieser Zeile den Wert 10014 hat. Jetzt klar?
%line% ist 10014; %line:~-2% wäre dann der Substring von 10014, die letzten 2 Stellen.
Und die Zahl 2 hole ich aus der Variablen %pN%.
Okay, mal sehen, ob jetzt noch was zum FindLongPath.bat zu sagen bleibt.
Dessen Aufbereitung sieht so aus (Zeile 14 und 50 nachbearbeitet):
01 :: Aufruf FindLongPath [Lw:/Pfad] [Pfadlänge]  
02 :: Default Lw:/Pfad=%temp%   
03 :: Default Pfadl"nge = 50    
04 @ECHO off & SETLOCAL ENABLEEXTENSIONS  
05 SET usedvars=tmpdatei reportdatei p1 p1masked p2 x YN PAUSE_D ECHO_D   
06 if Defined DebugMyBatches ((set ECHO_D=@ECHO) & (set PAUSE_D=pause) ) else ( set ECHO_D=REM)  
07 REM call :Debugshow_vars "Am Start der Batchdatei" ...bei Bedarf das REM entfernen    
08 CALL :paramcheck %1 %2  
09 :: Nicht einfach weiterlesen... hast Du geguckt, was in :paramcheck passiert???  
10 DIR %p1% /aD /b /s >%tmpdatei%  
11 IF exist "%reportdatei%" del "%reportdatei%"     
12 SET /a p2=%p2%-1  
13 SETLOCAL EnableDelayedExpansion  
14 FOR /F "delims=" %%i in (%tmpdatei%) do (set "x=%%i") && if "!x:~%p2%,10!" GTR "@" @echo %%i >>%reportdatei%    
15 IF EXIST "%reportdatei%" (    
16      ECHO Report wurde gespeichert als %reportdatei%.     
17      ECHO - Reportdatei vom %date% -- Alle Verzeichnisse >%p2% auf %p1% -->>"%reportdatei%"     
18      ECHO - Reportdatei "%reportdatei%" -->>"%reportdatei%"    
19      SET /p YN="Auf %p1% wurden Pfade mit L"nge gr"áer %p2% gefunden. Anzeigen (J/N?) "    
20      IF /i ""=="J" TYPE "%reportdatei%" |MORE         
21 ) ELSE (  
22      ECHO Keine Pfade l"nger als %p2% Zeichen im Pfad %p1% gefunden.    
23 )  
24 ENDLOCAL  
25 CALL :DebugShow_vars  
26 CALL :cleanup  
27 GOTO :eof  
28 -------------------  
29 ::::::::::::  ParamCheck ... Hier werden die Parameter %1 und %2 geprft daraus %p1% und %p2% abgeleitet.  
30 :: Param 1 : Laufwerksbuchstabe oder Verzeichnis; Default %temp%  
31 :::::::::::: Dieser Parameter wird als Substring in den Variablen %tmpdatei% und %reportdatei% verwendet   
32 :::::::::::: Dafr werden ":" und "\" durch "$" und"_" ersetzt, um einen gltigen Dateinamen zu bilden.    
33 :::::::::::: dazu Zwischenspeicherung in Variable %p1% und %p1masked%   
34 :::::::::::: Syntax dazu siehe SET /? und dort.. %PATH:str1=str2%  
35 :: Param 2:: zu prfende L"nge der Verzeichnisse ... Default 50    
36 :ParamCheck  
37 IF (%1)==() (SET p1=%temp%) ELSE (SET p1=%1)  
38 IF (%2)==() (SET /a p2=50 ) ELSE (SET /a p2=%2)  
39 SET p1masked=%p1::=$%  
40 SET p1masked=%p1masked:\=_%  
41 %ECHO_D% p1->p1masked ist %p1%->%p1masked%; p2 ist %p2%  
42 SET "tmpdatei=%temp%\%computername%_%p1masked%_All.lst"    
43 SET "Reportdatei=d:\temp\%computername%_%p1masked%_%p2%.lst"    
44 CALL :Debugshow_vars "Nach Var-Setzen"    
45 goto :eof  
46 --------------------  
47 :DebugShow_vars  
48 IF DEFINED DebugMyBatches (  
49 SETLOCAL ENABLEDELAYEDEXPANSION  
50 FOR %%i IN (%usedvars%) DO (ECHO [%~1]  Variable %%i="!%%i!" )     
51 ENDLOCAL  
52 PAUSE  
53 )  
54 GOTO :eof  
55 -----------------  
56 :cleanup  
57 %ECHO_D% in Subroutine :Cleanup  
58 IF EXIST "%tmpdatei%"  del "%tmpdatei%" & %ECHO_D% Datei %tmpdatei% wird gelöscht.  
59 FOR %%i IN (%usedvars% usedvars) DO @IF DEFINED %%i ( 
60     (IF DEFINED DebugMyBatches echo %%i wird freigegeben) & (SET %%i=))
60a REM **s.u.       (IF DEFINED ECHO_D %ECHO_D% %%i wurde freigegeben) & (SET %%i=))  
61 GOTO :eof  
62 ::---------End of FindLongPath.bat ------- 
ad 22, 32, 35 und 58 ja,ja.. die Umlaute gehen kaputt...nicht nur meine Schuld... Greeeezz @m$
Konsequenz: Umlaute sparsam verwenden in Batches - auch im Jahr 2005 und bei 64-Bit-Architekturen!
ad 04 @echo off & SETLOCAL ENABLEEXTENSIONS ... EnableExtensions ist Standard bei W2k-XP. Hätte ich mir schenken können, Dann wäre es kürzer geworden.
ad 05 Brauche ich für nur meine Pseudo-Debug-Mimik. Wäre sonst auch überflüssig.
ad 06 Eine meine Standardzeilen in Batches (per Copy & Paste). Damit kann ich Batches Zeilen einbauen, die im Normalbetrieb als Kommentar interpretiert werden, Wenn ich eine Variable "DebugMyBatches" vor dem Start der Batchdatei gesetzt habe, werden aus den "REM "-Kommentarzeilen Echo und Pause.Anweisungen.
Ach ja, geschwindelt war letztes Mal, dass ihr "Set DebugMyBatches=42" eingeben müsst. "Set DebugMyBatches=41" hätte auch gereicht.
ad 08 springt zu :ParamCheck in Zeile 36...ich jetzt auch
ad 37-38 Defaults bzw userdefininierte Parameter setzen
ad 39-40 Setze Wert von %p1masked% auf p1 (Laufwerk/Pfad), ersetze alle ":" und "\" durch "$" und "_"
ad 41 im Normalbetrieb Kommentarzeile, Im Debugmodus (%DebugMyBatches% gesetzt) eine Echo-Zeile
ad 42-43 Nix besonderes, außer.. dass sich statt SET VAR=wert auch SET "VAR=wert" schreiben lässt. Braucht man manchmal.
ad 44 Na klar, wer mitgelesen hat...ich hätte auch als Zeile 06a schreiben können :
if Defined DebugMyBatches (set "CALL_SHOW_VARS_D=call :Debugshow_vars") else set CALL_SHOW_VARS_D=REM
und Zeile 44 ändern auf %CALL_SHOW_VARS_D% "Nach Var-Setzen" ...da wäre der Batch im Normalbetrieb schneller. *gg ....aber im DebugMode Sprung zu 47-54
ad 52 Da hatte ich zuerst ein %PAUSE_D% stehen...aber ist ja Unsinn. Da kommt er nur im Debugmodus hin.
Bugfix 58 und 60 siehe unten, Posting und Fix von JohnnyB
ad 45 und Return To Caller...zurück zu Zeile 08...ganz ans Ende davon..
ad 10 Alle Verzeichnisse z'amsammeln in einer Textdatei..
ad 12 SET /a p2=%p2%-1 ..an ja, nicht ganz sauber.. Richtig wäre gewesen: SET /a p3=%p2%-1, aber ich wollte keine zusätzliche Variable p3 definieren und habe %p2% um eins gemindert, weil ich das später als Substring-Parameter brauche. Geschlampt. Aber is ja auch nur 'n Batch. *trotzdem schäm*
ad 13 SETLOCAL EnableDelayedExpansion... kennt ihr ja jetzt
ad 14 FOR /F "delims=" %%i in (%tmpdatei%) do ....mit allen Zeilen der %tmpdatei%
(set "x=%%i") && ...... jede Zeile in Variable x speichern und dann...
if "!x:~%p2%,10!" GTR "@" ... und alle Zeilen mit Substring(p2, 10) größer ist als "@"
@echo %%i >>%reportdatei% ... in die Reportdatei anhängen.
ad 15-23 Nix Aufregendes
ad 24 ENDLOCAL ist die Klammerzu zu Zeile 13.
ad 25 siehe ad 44
ad 26 alte Gewohnheiten..nach dem Variablen definieren auch wieder alle löschen.
27 GOTO :eof ...Hier nun wirklich ein Return. Gehe zum Ende der Welt. Bzw. des Batches.

So, ein bisschen was hebe ich mir noch für den nächsten Teil des Workshops auf.
Für heute noch eine kleine Kuriosität zun FOR...IN..DO -Befehl.
Laut Dokumentation sind als Zählvariablen erlaubt %a...bis %z und %A..bis %Z.
Also müsste doch folgende Anweisung einen Syntaxfehler melden:
>FOR %@ IN (Microsofts Praktikanten können super programmieren) do @echo %@
Probierts aus Auch gern mit "FOR %! IN...DO".

Frank / der Biber aus Bremen

P.S. Für alle, die nur mitgelesen haben wegen der versprochenen GetIP.Bat's ...nächstes Mal.
Na gut, einen letzten Oneliner noch ...
::-------snipp--GetIPviaPing.bat (dt. Bei US-Version "Reply" statt "Antwort" ---  
for /F "Tokens=3 Delims=: " %%i in ('@ping -n 1 "%computername%"^|Find "Antwort"') do ( set IP=%%i )  
:: ------snapp--GetIPviaPing.bat ---  

Weiter geht es hier:
Workshop Batch for Runaways - Part III - Datums- und Zeitvariablen im Batch

...und immer passend zum Workshop:
Tutorial zur FOR-Schleife von Friemler

Content-ID: 14413

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

Ausgedruckt am: 21.11.2024 um 18:11 Uhr

18992
18992 21.10.2005 um 13:25:35 Uhr
Goto Top
<font color=red>:GuruStuff</font>
Okay, ich versuch mal ein paar
Möglichkeiten auzuzeigen, die beim
Rumbätcheln so möglich sind.
Ich wollte ja ein paar Worte zu dem
FindLongPath.bat aus dem Teil 1 des kleinen
Workshops sagen.
Dazu wäre es sinnvoll, diesen Batch
nochmal hier zu posten, aber mit
Zeilennummern. Ist einfacher.
Hmm..soll ich sowas zu Fuß machen,
Copy & Paste und dann Zeilennummern
eingeben? Wer bin ich denn?
Das lass ich mal ein
20-Zeilen-Bätchelchen machen, ...

...Ähm oder ich tippe:

echo |findstr /n .* quelldatei.bat > zieldatei.txt

in meine CMD und bekomme gleiches Ergebnis.

Nix für ungut ;)
LG

Rantanplan
Biber
Biber 21.10.2005 um 14:09:21 Uhr
Goto Top
face-wink @Rantanplan

Das ist halt immer die Schwierigkeit bei Tutorials, halbwegs sinnvolle Beispiele zu konstruieren..
In einem der neueren Kommentare in diesem Thread gibt es z.B. die Durchnumeriervariante in der Form, dass
1=VerzeichnisnameA
2=VerzeichnisnameB
...
in eine Pseudo-Ini-Datei geschrieben werden soll. Da passt die Mimik auch ohne große Anpassungen.
Es sollte hier wirklich nur der (vielleicht ungeschickte) Versuch sein, ein bisschen mit FOR..IN..DO.. rumzukaspern, um es dem einen oder der anderen etwas näher zu bringen.
Ich bin natürlich auch gern offen für bessere Beispielanwendungen.

Danke Dir für die Rückmeldung und wünsche ein schönes Wochenende

Frank / der Biber aus Bremen

P.S. Natürlich werde ich mich in Zukunft auch mit so neumodischem Krams wie FindStr auseinandersetzen müssen und nehme Deinen Tipp schon mal als Einstieg. face-smile
ahe
ahe 03.05.2006 um 14:30:10 Uhr
Goto Top
Hallo Biber,

erst einmal ein großes Lob und Danke für deine tollen Tuts und Anregungen und mach'
bitte weiter.

Eine Anmerkung hätte ich dann aber doch noch...

Aus eigener Erfahrung weiss ich, dass es mitunter schwer ist den eigenen Text, die eigenen
Doks oder Sourcen zu lesen, zu korrigieren und zu setzen, daher ein kleiner Hinweis:

In Abschnit h) ist glaube ich ein c'n'p error hineingekommen face-smile

(dir /b *.lod>nul 2>nul) && (echo Fehler bei beim Dir-Befehl, Errorlevel ist %ERRORLEVEL% & goto :end)

müßte dies nicht eher so heißen:

Dann taucht noch der folgenden String unterhalb des Textblocks zur Ausrufezeichen.txt auf:
</font size=-2>


Noch einmal, eine tolle Arbeit, es zeigt mir außerdem die 'DOS'-Batches sind nicht tot und
meine 'kruden' Automatisierungs-Ideen lassen sich auch damit noch lösen face-smile

mfg
Axel
Biber
Biber 03.05.2006 um 15:05:36 Uhr
Goto Top
Moin Axel,
danke für die Blumen und die Hinweise.

Richtig wäre, wie Du auch geschrieben hast:
(dir /b *.lod>nul 2>nul) || (echo Fehler bei beim Dir-Befehl, Errorlevel ist %ERRORLEVEL% & goto :end) 

Auch mit dem zweiten Hinweis hast Du recht, dieses "fontsize=-2" hängt in der Luft.
Es sieht sogar im Original noch schlimmer aus - durch die Umstellung auf neue Formatierungs-Konventionen sind einige der "alten" Formatierungstags automatisch gelöscht, andere "nur" unwirksam, wieder andere anders interpretiert worden als vorher.
Führt dazu, dass -unter HTML-Gesichtspunkten im Moment zwar ein stabiles Ungleichgewicht von öffnenden/schließenden Tags im Quellcode besteht, aber das einzige, was davon optisch durchschlägt, ist dieses eine sichtbare Tag "fontsize=-2".
(Es sind mehrere öffnende Tags ohne schließendes Gegenstück oder vice versa.)
Wenn ich dieses herauslösche -ich habe es eben nochmal probiert - kann ich den Beitrag nicht mehr speichern nach dem Editieren.

Denk es Dir einfach weg face-wink
Grüße
Biber
JohnnyB
JohnnyB 21.08.2006 um 02:06:15 Uhr
Goto Top
Schönes Tutorial, Biber!
> set /a bewertung=5

Ich habe das alles mal nicht per cnp, sonder per 10-Fingers ausprobiert und dabei einen Fehler entdeckt, der hier zwar nicht viel ausmacht, aber in anderen Situationen u.U. graue Haare verursacht. Hier führt er dazu, daß die :cleanup Routine nicht funktioniert:

In Zeile 06 setzt Du für den Fall, daß die Umgebungsvariable DebugMyBatches nicht gesetzt ist, die Variable ECHO_D auf REM. Das Problem dabei ist, das alles was dann nach dem REM in einer Zeile steht ignoriert wird und noch schlimmer, ein REM in einer FOR ... IN ... DO -Schleife zum Abbruch dieser Schliefe führt. Zumindest tut es das in den Zeilen 59/60.

Das Fatale an der Sache ist, daß während des Debuggings alles ganz normal läuft, und wenn man sich dann entschließt, die Debugging-Anzeige auszuschalten, sprich die DebugMyBatches wieder zu löschen, fängt der Mist an. In diesem konkreten Beispiel heißt das, das tmpfile wird nicht gelöscht und die Variablen bleiben auch nach Beendigung des Batch im Speicher.

Folgende Änderung der Zeilen 58 und 60 schaffen da Abhilfe:
58 IF EXIST "%tmpdatei%" (del "%tmpdatei%") & %ECHO_D% Datei %tmpdatei% wird gelöscht.  
...
60 	(IF DEFINED DebugMyBatches echo %%i wird freigegeben) & (SET %%i=))


In Zeile 58 wird also zuerst die tmpdatei gelöscht und ggf. anschließend ausgegeben, wenn hier dann ein REM steht ist es egal. In Zeile 60 wird nicht ECHO_D abgefragt, denn das ist ja auf jeden Fall definiert, entweder als ECHO oder eben als REM und das REM können wir hier absolut nicht gebrauchen. Wenn also DebugMyBatches definiert ist, dann wird ausgegeben, welche Variable wieder freigegeben wird, ansonsten ist Ruhe.

Wie gesagt, in diesem Fall war der Fehler nicht so schlimm, wenn jedoch so ein REM in einem Anweisungsblock mit kritischen Anweisungen steht, können schon mal komische Sachen passieren. Und den Fehler dann zu finden kann richtig blöd werden, weil wenn man das Debugging dann aktiviert tritt der Fehler nicht mehr auf. So etwas kann einen den letzten Nerv kosten.

Schönen Gruß,
Johnny.
Biber
Biber 21.08.2006 um 04:04:22 Uhr
Goto Top
Thx, JohnnyB,
für Finden und Fixen des Bugs.
Hast natürllich vollkommen Recht - aber das passiert mir oft, wenn ich Batches mit mehr als einer Zeile zu schreiben versuche. face-wink

Leider konnte ich Deine Korrektur nicht oben in das Tutorial direkt einbauen.. face-sad
...- sobald ich das editiere (wie vorsichtig auch immer),
bekomme ich eine SQL-Fehlermeldung von WebMaster Scholls mySQL-Geraffel "Fehler beim Update...bla".
Sprich - das Tutorial muss leider mit allen inhaltlichen, orthografischen, Rechtschreib- und Formatierungsfehlern so da stehen bleiben wie es ist.
Da es schon mal in der DB drin ist, wird es akzeptiert, aber es geht offensichtlich nicht mit den jetzt gültigen Mindestanforderungen konform.

Wenn ich mal gaaaaaaanz viel Zeit und/oder eine blutjunge rothaarige Praktikantin habe, dann werde ich das Ding nochmal komplett auf die (damals) neu einführten Formatierungsregeln anpassen.

Also, falls ihr dieses Forum unterstützen wollt, und die Handynummer einer blutjungen rothaarigen Praktikantin
(EDV-Kenntnisse sind nicht zwingend erforderlich!) kennt.... ihr wisst ja, wo ihr mich findet.

Danke nochmal für den Hinweis und das Fixen des Bugs.

Grüße
Biber
Biber
Biber 23.08.2006 um 22:30:28 Uhr
Goto Top
Nun war ich mal wieder - für meine Verhältnisse - wirklich sprachlos.

Vollkommen unerwartet fand ich heute eine PN und eine Mail von Kollege @JohnnyB vor
mit einer komplett bereinigten und an die "neuen" Formatierungsregeln angepassten Version des Tutorials oben...
...da war ich platt.

Ich habe es oben eingesetzt, noch den von Johnny gemeldeten Bugfix eingebaut und glaube wieder an das Gute in uns allen Admins... face-wink

GANZ DICKES DANKE, JohnnyB!!

Liebe Grüße
Biber
...der bei solchen Gesten auch gern auf blutjunge, rothaarige Praktikantinnen verzichtet
d00meR
d00meR 13.09.2006 um 11:25:36 Uhr
Goto Top
Sehr netter Workshop, vielen Dank.

Das einzige was ich nicht verstehe ist: @Biber, WTF? Wieso verzichtest du auf BLUTJUNGE, ROTHAARIGE Praktikantinnen ??? ;)

Gruß, Daniel
doc-jochim
doc-jochim 23.08.2008 um 01:32:27 Uhr
Goto Top
@Biber

Ich habe gerade mal ein bißchen mit der o.g. Batchdatei herumgebastelt, da ich ein Tool gesucht habe, das mir zu
lange Dateinamen, die durch Verschieben von Ordnern entstanden sind, herausfindet.

Beim Übertragen der Dateien von dem Ordner 'C:\Eigene Dateien\...' von meinem alten Win98-Rechner in das neue
XP-Verzeichnis 'C:\Dokumente und Einstellungen\Benutzername\Eigene Dateien\...' ist der Pfad nicht unerheblich
(fast 30 Zeichen) länger geworden face-sad

Leider ist mir hier bei dem vorliegenden Batch-File aufgefallen, daß manches nicht so funktioniert wie angedacht:

Zuerst mußte ich in der Zeile
10 DIR %p1% /aD /b /s >%tmpdatei%
die Option /aD entfernen, denn sonst werden nur Verzeichnissnamen, nicht aber die Dateinamen auf die Länge
überprüft.

Weiterhin besteht das Problem, daß offensichtlich in Zeile 15-24 die mit set /p zugewiesene Variable YN bei der
Schlußabfrage für das Anzeigen des Inhaltes der erstellten Report-Datei nicht benutzt werden kann. Erst wenn
die Zugriffe auf die Variable außerhalb der Klammer der If exist-Abfrage erfolgen, funktioniert die Abfrage. Innerhalb
der Klammer komischerweise nicht?!?

Woran kann das liegen?

Hmmmm... - auf jeden Fall habe ich lange herumprobiert, um dann kurzerhand - vielleicht geht es eleganter - eine
funktionierende Schlußabfrage zu erstellen:

IF NOT EXIST "%reportdatei%" ECHO Keine Pfade laenger als %p2% Zeichen im Pfad %p1% gefunden. & goto :Ende
ECHO Report wurde gespeichert als %reportdatei%.
ECHO - Reportdatei vom %date% -- Alle Verzeichnisse >%p2% auf %p1% -->>"%reportdatei%"
ECHO - Reportdatei "%reportdatei%" -->>"%reportdatei%"
SET /p YN="Auf %p1% wurden Pfade mit Laenge groesser %p2% gefunden. Anzeigen [J/N?]"
if "%YN%"=="j" TYPE "%reportdatei%" |MORE
:Ende
ENDLOCAL

Und noch etwas ist mir aufgefallen: Es gibt Probleme mit dem Angeben des Pfades, auf den die Datei angewendet
werden soll:

Wenn es z.B. um C:\Dokumente und Einstellungen geht, wird nicht der gesamte Name als Verzeichnis erkannt.
Gebe ich den Pfad dann in "" ein ("C:\Dokumente und Einstellungen"), dann gibt es Probleme mit der zu erstellenden
Datei, da das Batchfile versucht, den Pfad mitsamt den Anführungszeichen in den Dateinamen einzubauen.

Allerdings habe ich noch keine Idee, wie man dies umgehen kann. Wahrscheinlich müsste man eine zusätzliche
Hilfsvariable schaffen, in der der Pfad ohne die Anführungszeichen abgelegt wird.

Aber vielleicht habt Ihr als Profis hier im Forum ja die passenden Vorschläge face-smile

André
bastla
bastla 24.08.2008, aktualisiert am 21.04.2016 um 19:13:43 Uhr
Goto Top
Hallo doc_jochim!

Mit ein paar eingestreuten Anführungszeichen (und anderem Kroppzeug face-wink) sollte es auch mit "C:\Dokumente und Einstellungen" klappen ...
Da die Ausgabe mit "type" (vor allem bei kleineren Werten für die zu prüfende Länge) etwas mühsam werden kann, habe ich ersatzweise einen "notepad"-Aufruf eingebaut.
Noch ein Hinweis zur %reportdatei%: Das Verzeichnis, in welchem diese erstellt werden soll (siehe Zeile 43) muss bereits existieren ...

:: Aufruf FindLongPath [Lw:/Pfad] [Pfadlänge]
:: Default Lw:/Pfad=%temp%
:: Default Pfadl"nge = 50 
@ECHO off & SETLOCAL ENABLEEXTENSIONS
SET usedvars=tmpdatei reportdatei p1 p1masked p2 x YN PAUSE_D ECHO_D
if Defined DebugMyBatches ((set ECHO_D=@ECHO) & (set PAUSE_D=pause) ) else ( set ECHO_D=REM)
REM call :Debugshow_vars "Am Start der Batchdatei" ...bei Bedarf das REM entfernen  
CALL :paramcheck %1 %2
:: Nicht einfach weiterlesen... hast Du geguckt, was in :paramcheck passiert???   
DIR "%p1%" /s /b >"%tmpdatei%"  
IF exist "%reportdatei%" del "%reportdatei%"  
SET /a p2=%p2%-1
SETLOCAL EnableDelayedExpansion
FOR /F "usebackq delims=" %%i in ("%tmpdatei%") do (set "x=%%i") && if "!x:~%p2%,10!" GTR "@" @echo %%i >>"%reportdatei%"  
IF EXIST "%reportdatei%" (  
     ECHO Report wurde gespeichert als %reportdatei%.
     ECHO - Reportdatei vom %date% -- Alle Verzeichnisse ^>%p2% auf %p1% --^>^>"%reportdatei%"  
     ECHO - Reportdatei "%reportdatei%" --^>^>"%reportdatei%"  
     SET /p YN="Auf %p1% wurden Pfade mit L„nge gr”áer %p2% gefunden. Anzeigen (J/N?) "  
     IF /i "!YN!"=="J" notepad "%reportdatei%"  
) ELSE (
     ECHO Keine Pfade l"nger als %p2% Zeichen im Pfad %p1% gefunden.  
)  
ENDLOCAL
CALL :DebugShow_vars
CALL :cleanup
GOTO :eof
-------------------
::::::::::::  ParamCheck ... Hier werden die Parameter %1 und %2 geprft daraus %p1% und %p2% abgeleitet.
:: Param 1 : Laufwerksbuchstabe oder Verzeichnis; Default %temp%
:::::::::::: Dieser Parameter wird als Substring in den Variablen %tmpdatei% und %reportdatei% verwendet
:::::::::::: Dafr werden ":" und "\" durch "$" und"_" ersetzt, um einen gltigen Dateinamen zu bilden. 
:::::::::::: dazu Zwischenspeicherung in Variable %p1% und %p1masked%
:::::::::::: Syntax dazu siehe SET /? und dort.. %PATH:str1=str2%
:: Param 2:: zu prfende L„nge der Verzeichnisse ... Default 50
:ParamCheck
IF (%1)==() (SET "p1=%temp%") ELSE (SET "p1=%~1")  
IF (%2)==() (SET /a p2=50 ) ELSE (SET /a p2=%2)
SET "p1masked=%p1::=$%"  
SET "p1masked=%p1masked:\=_%"  
%ECHO_D% p1-^>p1masked ist %p1%-^>%p1masked%; p2 ist %p2%
SET "tmpdatei=%temp%\%computername%_%p1masked%_All.lst"  
SET "Reportdatei=D:\Temp\%computername%_%p1masked%_%p2%.lst"  
CALL :Debugshow_vars "Nach Var-Setzen"  
goto :eof
--------------------
:DebugShow_vars
IF DEFINED DebugMyBatches (
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%i IN (%usedvars%) DO (ECHO [%~1]  Variable %%i="!%%i!" )  
ENDLOCAL
PAUSE
)
GOTO :eof
-----------------
:cleanup
%ECHO_D% in Subroutine :Cleanup
IF EXIST "%tmpdatei%" del "%tmpdatei%" & %ECHO_D% Datei %tmpdatei% wird gel”scht.  
FOR %%i IN (%usedvars% usedvars) DO @IF DEFINED %%i (
    (IF DEFINED DebugMyBatches echo %%i wird freigegeben) & (SET %%i=))
 REM **s.u.       (IF DEFINED ECHO_D %ECHO_D% %%i wurde freigegeben) & (SET %%i=)) 
GOTO :eof
::---------End of FindLongPath.bat ------- 
Grüße
bastla

@Biber - Entschuldige bitte, dass ich Deine Abwesenheit ausnutze, mich an Deinem Batch zu vergreifen ... face-smile
doc-jochim
doc-jochim 25.08.2008 um 21:28:17 Uhr
Goto Top
Hallo bastla,

Noch ein Hinweis zur %reportdatei%: Das Verzeichnis, in welchem diese erstellt werden soll (siehe Zeile 43)
muss bereits existieren ...

Wie wäre es denn dann noch mit einer Sicherheitsabfrage, damit es nicht nach stundenlangem Durchsuchen
tief verschachtelter Verzeichnisbäume einen Fehler beim Schreiben der Report-Datei gibt.

Etwa in der Art:

FOR /f "delims=" %%i IN ('ECHO %Reportdatei%') DO (
IF NOT EXIST "%%~di" (ECHO Das für die Ergebnisdatei angegebene LW %%~di existiert nicht & goto :eof)
IF NOT EXIST "%%~dpi" (MD "%%~dpi"))

als Zeilen 8a, 8b und 8c.

So habe ich mir zumindest meine Sicherheitsabfrage gestrickt, bei dem Versuch, das Problem zu lösen.

FOR /F "usebackq delims=" %%i in ("%tmpdatei%") do (set "x=%%i") && if "!x:~
%p2%,10!" GTR "@" @echo %%i >>"%reportdatei%"

Warum eigentlich @echo, wenn oben sowieso schon @echo off steht?

ECHO - Reportdatei "%reportdatei%" --^>^>"%reportdatei%" (Zeile 18)

Irgendwie ist das ein bißchen doppelt gemoppelt. Hier steht gegenüber Zeile 17 doch keine zusätzliche Information - oder?

SET /p YN="Auf %p1% wurden Pfade mit L„nge gr”áer %p2% gefunden. Anzeigen (J/N?) "

Warum eigentlich nicht der gute, alte Choice-Befehl? Dann könnte man sich das Drücken der Enter-Taste sparen face-wink


Ich bin mir leider bzgl. des korrekten Syntax einiger Befehle im Moment noch nicht ganz so sicher, da ich mich im
Rahmen der Notwendigkeit zur Übertragung eines durch Verschieben und Umbenennen von Ordnern fehlerhaft
gewordenen Verzeichnisbaums mit zu langen 'Ästen' erst seit einigen Tagen mit den Batch-Befehlen beschäftigt habe.

Zur Info habe ich meine Version als gezippte 'files.bat' mal zum Download unter
http://www.urlaub-in-sorgenlos.de/fehler/pfadbatch.zip zum Anschauen hinterlegt.

Ich habe leider ein bißchen an den REMs und damit an der Dokumentation gespart. Aber bei Fragen einfach fragen face-smile

Ein Posten des kompletten Codes würde hier sicherlich nicht dazu führen, daß der Thread übersichtlicher wird...

André
ahe
ahe 26.08.2008 um 09:06:32 Uhr
Goto Top
Hallo André,

choice gibt es standardmäßig nicht mehr unter XP, "SET /p" dagegen schon... face-smile

Bin 'mal gespannt, was Biber zum interessanten Threadverlauf sagt, wenn er wieder da ist... face-smile

mfg
Axel
Biber
Biber 29.08.2008 um 00:26:05 Uhr
Goto Top
Moin doc_jochim, bastla und ahe,

vielen Dank für das Feedback und das aufmerksame und kritische Mitlesen/Mitdenken.

Im Einzelnen:

@bastla
Danke für das Perfektionieren.

@ahe
Bezüglich choice.com hätte ich es nicht anders (aber natürlich vieeeel wortreicher) formuliert. Das ist gottseidank abgelöst durch SET/P.
Choice.com und ForFiles.exe waren/sind aus meiner Sicht die in den letzten Jahren herausragendsten Verirrungen, die durch die Redmonder Qualitätskontrolle geschlüpft sind. Bestenfalls noch getoppt vom NT-Passwort-Verschlüsselungs-Algorithmus und dem Outlook-Winmail.dat-Desaster.
Oder neutraler ausgedrückt: choice.com in einem "Tutorial" zu verwerten hätte nach meinem Empfinden etwas unfreiwillig Komisches.

@doc_jochim
Deine Anpassungen/Vereinfachungen/Verschlankungen sind durchaus berechtigt und auch die ünnötigen "@echo"-Befehle und doppelten "ich bin die Reportdatei"-Zeilen gehören nicht in einen "produktiv" eingesetzten Gebrauchsbatch.

Aber die Intention dieses Tutorials war auch eher, die Herangehensweise an eine mittelkomplexe Aufgabenstellung mit dem scheinbar klobigen und unstrukturierbaren Werkzeug CMD-Interpreter aufzuzeigen.
Oder, wie ich es weiter oben irgendwo formuliert habe - was sollte ich beachten, wenn ich einen Batch schreiben muss, der voraussichtlich mehr als 20 Zeilen lang werden wird und der garantiert nicht im ersten Anlauf in allen Prozessverästelungen "fehlerfrei" funktionieren wird.
Diese "Diskussion" sollte mein beabsichtigter Schwerpunkt sein sowohl bei der NumberMe-Spielerei wie auch dem FindLongPath-Beispiel.

Meine Absicht war nicht, die ultimative out-of-the-box-solution mit der 5-Jahre-Unterwasserlaufgarantie bereitzustellen. Sondern viel bescheidener: Wenn diese Skizzen dazu geführt haben, dass der eine oder andere Ansatz tatsächlich in real vor sich hinschnurrenden Gebrauchsbätchen irgendwo "in der richtigen Welt" weiterlebt... dann hat diese Anleitung ihren Sinn erfüllt.

Grüße
Biber
doc-jochim
doc-jochim 29.08.2008 um 22:06:57 Uhr
Goto Top
@Biber

Choice.com und ForFiles.exe waren/sind aus meiner Sicht die in den letzten Jahren herausragendsten Verirrungen,
die durch die Redmonder Qualitätskontrolle geschlüpft sind.

Hmmm... - da habe ich wohl was nicht mitbekommen. Ich fand die Abfrage bisher immer ganz praktisch, wenn nur ein Zeichen gefordert war. Dann konnte man sich das Drücken der Return-Taste sparen.

Was ist denn so schlimm an dem choice-Befehl?

Meine Absicht war [...] viel bescheidener: Wenn diese Skizzen dazu geführt haben, dass der eine oder andere Ansatz tatsächlich in real vor sich hinschnurrenden Gebrauchsbätchen irgendwo "in der richtigen Welt" weiterlebt... dann hat diese Anleitung ihren Sinn erfüllt.

Bummbummm...bummbummm...bummbummm... Es lebt und die Ideen haben mir sehr weitergeholfen.

Gibt es eigentlich eine Möglichkeit, die in Dateinamen hineingerutschten Ähs, Öhs, Ühs, Esszetts... in der Report-Datei so darzustellen, daß man sie nicht unbedingt mit den edit-Befehl anschauen muß, sondern daß ein Öffnen im Notepad oder in Word möglich ist, ohne daß die Zeichen durch komische Symbole ersetzt werden?

André
bastla
bastla 29.08.2008, aktualisiert am 18.10.2012 um 18:36:10 Uhr
Goto Top
Hallo doc_jochim!

Um Dir hoffentlich das Suchen (bzw einen neuen Beitrag) zu ersparen: face-wink Pfadangaben mit Umlauten

Grüße
bastla
dbernsee
dbernsee 21.04.2016 aktualisiert um 14:36:47 Uhr
Goto Top
@Biber

Erst mal ein fettes Lob an Dich für diesen Super Workshop...Alle Daumen gehen hoooch face-smile

Allerdings hätte ich da doch noch ein Punkt der leider unbeantwortet bleibt.

Ich hätte gerne die Prozessor Architektur bzw. Betriebssystem Variante in einer Zeile abgefragt...meine Idee war folgende:

if "%PROCESSOR_ARCHITECTURE%" == "x86" (set progdir=%ProgramFiles%) ELSE (set progdir=%ProgramFiles(x86)%)

das führt aber zu einem Syntax Fehler, da in der x86 Systemvariable bereits eine Klammer enthalten ist!

Ich habe bereits versucht diese mit einem ^ zu maskieren...ohne erfolg! -> Gibt es hier evtl. ein anderes Zeichen das man nutzen kann ...oder man benutzt für die unterteilung der zwei set commandos etwas anderes statt den normalen Klammern!?

als workaround habe ich es z.zt. so gelöst (gefällt mir persönlich eher weniger)

if "%PROCESSOR_ARCHITECTURE%" == "x86" goto x86
set progdir=%ProgramFiles(x86)%
goto copyjob

:x86
set progdir=%ProgramFiles%

:copyjob


Vielleicht habt ihr ja noch eine Idee!?

Gruß
Dirk


Nachtrag:

folgende Zeile hat dann jetzt doch funktioniert...aber das Ergebnis ist irgendwie nicht wie erwünscht

if "%PROCESSOR_ARCHITECTURE%" == "x86" (set progdir=%ProgramFiles%) ELSE (set progdir=%ProgramFiles^(x86^)%)

der Output ist dann aber keine Variable sondern Text!
C:\>echo %progdir%
%ProgramFiles(x86)%

ich dachte das hätte ich schon mal Probiert und es hatte garnicht funktioniert...aber egal!
bastla
bastla 21.04.2016 um 16:14:09 Uhr
Goto Top
Hallo dbernsee!

Hast Du es schon so versucht?
if "%PROCESSOR_ARCHITECTURE%" == "x86" (set "progdir=%ProgramFiles%") ELSE (set "progdir=%ProgramFiles(x86)%")
Grüße
bastla
dbernsee
dbernsee 21.04.2016 um 18:34:24 Uhr
Goto Top
Heilige Sch...

...da hätt ich aber auch selber drauf kommen können!

Aber wie sagt man so schon...hätt der Fuchs nich geschissen hätt er die Gans gefangen...oder so ähnlich face-smile

1000 Dank!

Gruß
Dirk
Biber
Biber 21.04.2016 um 18:48:00 Uhr
Goto Top
[OT]
Ehrlich, es Ist wirklich nicht so, dass ich nicht mehr bereit wäre, auf nachtröpfelnde Fragen zu antworten....

Ich bin einfach zu langsam.
Oder andere haben mehr Prozessorkerne....

@ bastla
Jedenfalls vielen Dank für's Aushelfen... also für das heute und das davor vor 6 Jahren face-wink

Grüße
Biber
[/OT]
bastla
bastla 21.04.2016 um 19:11:58 Uhr
Goto Top
[OT] @ Biber

Du bist ja nicht langsam, Dein Montach dauert vermutlich nur einfach schon zu lang ... face-wink

Was das Aushelfen angeht: immer noch gerne face-smile (bin aber mittlerweile vergleichsweise selten hier).

Grüße
bastla
[/OT]