I am trying to make a batch where it searches for all files that contain log4j-core and stores all the path to a text file so I can copy a new updated file with a different version to all the paths that were found. This is what I have so far.
SetLocal EnableDelayedExpansion
cd \
ECHO SEARCHING FOR log4j-core THIS MAY TAKE SOME TIME...
dir /s /b log4j-core*.jar >%tmp%\path.txt
echo delims
for /f "delims=" %%a in (%tmp%\path.txt) do (set path=%%~dpa && copy /b /y "c:\Temp\Script\patch.jar" "%path%\log4j-core-2.17.2.jar")
pause
CodePudding user response:
Although you don't actually ask a question, there are problems with your code.
%temp%
by default contains spaces, hence you need to quote %tmp%\path.txt
wherever it is used, thus: "%tmp%\path.txt"
This means that you need "usebackq delims="
in your for /f
otherwise the for
will analyse the string "%tmp%\path.txt"
, not the file "%tmp%\path.txt"
as intended.
Next problem is the set
statement. Batch is sensitive to spaces in an ordinary string SET
statement. SET FLAG = N
sets a variable named "FLAGSpace" to a value of "SpaceN". Use set "var1=value"
for setting STRING values - this avoids problems caused by trailing spaces.
Don't use path
as a variablename - it's a reserved word in batch, meaning the sequence in which the directories are searched to find an executable that isn't in the current directory.
Next is the minor matter of delayedexpansion
. You are invoking delayedexpansion
but not using it. Please read Stephan's DELAYEDEXPANSION link
Once we've tackled all of that, we come to simplification.
Whatever variable name you use, %~dp?
returns the pathname including a terminal backslash, so you don't need to insert it again in the destination filename for your copy
.
You don't need to use the intermediate variable - only if you are manipulating the string. "%%~dpaog4j-core-2.17.2.jar"
will work quite adequately for your copy-destination, remembering that %%~dpa
will be resolved to a string with terminal backslash.
The echo
statement will simply display the string delims
and seems pointless.
It's probably academic, but the dir
command should contain /a-d
to exclude any directory names that match the pattern, unlikely though that may be.
I'd also suggest that where /r \ log4j-core*.jar
should produce the same results as the dir
command. Note that there are two parameters to where /r
- a directory name and a filename-pattern to match. If the filename-pattern does not have an extension, it required a terminal .
otherwise .*
is assumed.
And finally, for /f
can process the list produced by a command, see for /?
from the prompt or thousands of examples on SO.
So, all in all, your code could be reduced to
for /f "delims=" %%a in ('where /r \ log4j-core*.jar') do copy /b /y "c:\Temp\Script\patch.jar" "%%~dpalog4j-core-2.17.2.jar"
Always verify against a test directory before applying to real data.
It would be wise to simply echo
the copy
command for verification
And I'll say again, always verify against a test directory before applying to real data.