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
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