2016-03-30 12 views
1

Irgendwelche Ideen, warum das nicht funktionieren würde? Ich habe versucht, %A% durch %%f im Unterprogramm zu ersetzen, aber es würde sowieso nicht funktionieren.Batch-Unterroutine in for-Schleife

SETLOCAL EnableDelayedExpansion 
    for %%f in (*.bat) do (set A=%%f call :subroutine %%f) 

    :subroutine 
    findstr windowsisajoke %A% 
    if %errorlevel%==0 
    goto end 
    copy %0 %A% 
    :end 

Der Ausgang zeigte so etwas wie dieses:

FINDSTR: call cannot be opend. 
    FINDSTR: :subroutine cannot be opend. 
    test.bat:findstr windowsisajoke %A% 
    FINDSTR: pause cannot be opend. 

Bitte sagen Sie mir, was mit diesem Code falsch ist, ich versuche es richtig für wie 3 Tage jetzt :).

Wie immer wird jede Hilfe geschätzt! Vielen Dank !

Dies scheint zu akzeptieren, für die% 1-Datei. Das Programm setzt% errorlevel%: 0 == 0 und wird ohne zu kopieren beendet. Das Programm einfach den Befehl nicht unter der Hilfe Errorlevel-Prüfung durchführt !:

for %%f in (*.bat) do (
     findstr windowsisajoke %1 
     if not %errorlevel%==0 
     copy "%0" "%1" 
    ) 
+1

Es gibt die folgenden Probleme in Ihrem (ersten) Code: 1. Sie verketten zwei Befehle, also müssen Sie '&' verwenden, wie 'set" A = %% f "& call: subr outine %% f'; andernfalls weisen Sie die (literale) Zeichenkette '%% f call: Unterroutine %% f' der Variablen 'A' zu; die Anführungszeichen um den Ausdruck 'set' verhindern, dass nachfolgende Leerzeichen angehängt werden; 2. Sie stellen ein Argument für den Unterroutinenaufruf zur Verfügung, so dass Sie mit '% 1' oder besser noch mit'% ~1'' auf das Argument zugreifen müssen; 3. Setze den Suchstring in "" "wie" windowsisajoke "'; 4. Die gesamte 'if'-Anweisung muss in einer einzigen Zeile stehen, wie' if% ErrorLevel% EQU 0 goto: end' ... – aschipfl

Antwort

2

Zunächst einmal müssen Sie sicherstellen, dass Ihr Unterprogramm wird nach dem normalen Code nicht ausgeführt läuft:

rem code that calls the subroutine 

goto :eof 
:subroutine 
rem ... 

Sie müssen beenden, bevor Sie zu diesem Punkt gelangen.

Dann ist es eigentlich völlig klar, was passiert: Sie weisen den folgenden Wert auf die Variable %A%:

somefilename.bat call :subroutine %%f 

die, wenn sie in der unten stehenden findstr Aufruf eingefügt, weil Ihr Code dort läuft, führt zu Folgendes:

findstr windowsisajoke somefilename.bat call :subroutine somefilename.bat 

wo alles nach dem ersten Argument wird als ein Dateiname interpretiert werden. Wie du sehen kannst, ist das nicht das, was du willst.

Sie müssen keine Variablen in Ihrer Schleife festlegen, Sie können den Dateinamen einfach als Argument übergeben. Darüber hinaus werden auf die gleiche Weise als Argumente für Batch-Dateien Argumente zu Subroutinen behandelt: %1, %2, ...

So wird Ihr Code etwas wie folgt aus:

for %%f in (*.bat) do call :subroutine "%%f" 
goto :eof 

:subroutine 
findstr windowsisajoke %1 
if %errorlevel%==0 goto :eof 
copy "%0" "%1" 

ich mir die Freiheit nahm eine der Festsetzung einige Fehler, die mit Leerzeichen in Dateinamen brechen würden. Es ist auch nicht notwendig, am Ende der Datei ein Etikett zu haben, denn goto :eof macht das auch ohne ein solches Etikett. Es gibt jedoch noch ein Problem, weil Sie versuchen, die aktuelle Batch-Datei (%0) in die aktuell in der Schleife befindliche zu kopieren, die nicht innerhalb der Subroutine funktionieren kann, da %0 dort :subroutine ist. Daher müssen Sie auch den Batch-Datei-Namen in das Unterprogramm zu übergeben:

for %%f in (*.bat) do call :subroutine "%%f" %0 
goto :eof 

:subroutine 
findstr windowsisajoke %1 
if %errorlevel%==0 goto :eof 
copy "%2" "%1" 

Es gibt auch keine Notwendigkeit mehr für die verzögerte Expansion, weil man nie eine Variable gesetzt.

Jetzt

, können Sie auch ohne ein Unterprogramm all dies tun:

for %%f in (*.bat) do (
    findstr windowsisajoke "%%f" 
    if not %errorlevel%==0 copy "%0" "%%f" 
) 

oder sogar:

for %%f in (*.bat) do (
    findstr windowsisajoke "%%f" || copy "%0" ""%%f"" 
) 

und wenn Sie die Ausgabe nicht mögen, können Sie es einfach umleiten:

for %%f in (*.bat) do (
    findstr windowsisajoke "%%f" || copy "%0" ""%%f"" 
) >nul 2>&1 
for %%f in (*.bat) do (
    findstr windowsisajoke "%%f" || copy "%0" ""%%f"" 
) >nul 2>&1 
+0

* seufzt * nachdem ich drei Tage darüber nachgedacht habe und diese Antwort gelesen habe, die du vielleicht hätte haben können um herauszufinden, welchen Fehler ich gemacht habe, als ich den Code von einem Unterprogramm in einen Block umwandelte. – Joey

+0

Vielen Dank. Der letzte Code scheint jetzt zu funktionieren! Endlich! Nochmals vielen Dank für deine Hilfe, ich schätze es sehr, denn ich bin ziemlich neu in der Programmierung. Das hat eine Weile gedauert, aber die Ergebnisse sind erstaunlich. Vielen Dank :) –