Home > Enterprise >  Batch Search for file and copy path to copy a new file to the paths found
Batch Search for file and copy path to copy a new file to the paths found

Time:06-10

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.

  • Related