I have the following problem: I execute a windows batch file on a Jenkins server and have to split a multi-line environment variable (set vía a Jenkins parameter) into single li
You could echo
the variable out to a temporary txt file, then process that txt file line-by-line using a for /f
loop. You should also use delayed expansion to prevent the line breaks from being evaluated inappropriately.
@echo off
setlocal enableDelayedExpansion
:: // Test environment. Create a variable containing line breaks.
set BR=^
:: // note: The two empty lines above are required.
set "str=The quick brown!BR!fox jumps over!BR!the lazy dog."
:: // Test environment ready.
:: // Output to temporary txt file.
>"%temp%\tmp.txt" echo(!str!
:: // Process the txt file line by line.
set "line=0"
for /f "usebackq delims=" %%I in ("%temp%\tmp.txt") do (
set /a line += 1
echo Line !line!: %%I
rem // myprog.exe -baz 0 -meow %%I
)
:: // Delete temporary txt file.
del "%temp%\tmp.txt"
That should output
Line 1: The quick brown
Line 2: fox jumps over
Line 3: the lazy dog.
Or if you'd rather avoid temporary files, you could invoke another runtime to supply the environment variable to a for /f
loop. Here's a JScript hybrid example.
@if (@CodeSection == @Batch) @then
@echo off
setlocal enableDelayedExpansion
:: // Test environment. Create a variable containing line breaks.
set BR=^
:: // note: The two empty lines above are required.
set "str=The quick brown!BR!fox jumps over!BR!the lazy dog."
:: // Test environment ready.
:: // Invoke JScript to read the environment variable and return it line-by-line
set "line=0"
for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0"') do (
set /a line += 1
echo Line !line!: %%I
)
:: // end main runtime
goto :EOF
@end // JScript portion simply echoes %str% from the context of the current process
WSH.Echo(WSH.CreateObject('WScript.Shell').Environment('PROCESS')('str'));
Output is the same as above.
The FOR /F command takes the LF's inserted in the variable as lines separators (this is the natural behavior of FOR /F command), so nothing additional is required in order to process such variable with FOR /F:
@echo off
setlocal EnableDelayedExpansion
rem Create a variable containing line breaks.
set LF=^
%empty line 1/2%
%empty line 2/2%
set "str=The quick brown!LF!fox jumps over!LF!the lazy dog."
set line=0
for /F "delims=" %%a in ("!str!") do (
set /A line+=1
echo Line !line!: %%a
)
The key here is expanding the variable with !exclamationMarks!; otherwise the LF will cut the %value%. Also, if you want complete lines separated by LF, use "delims=". Output example:
Line 1: The quick brown
Line 2: fox jumps over
Line 3: the lazy dog.
Well as reflex I propose you the following solution:
If python is installed (if not ... up to you to install it .. it is usefull ;-) )
in your batch line : Python MyScriptToExecuteEachLinesFromVar.py varname "myprog.exe -baz 0 -meow"
With the script content:
import sys,os # libraries used : system and operating system
if len(sys.argv)>0: # if arguments provided (at least the variable name)
varname = sys.argv[1] # the variable name is the second argument (0=script)
prefix = " ".join(sys.argv[2:]) # the list of all others are the prefix.
lines = os.environ[varname].split('\n') # get the var and split lines
for f in lines :
print "execute:", prefix, f
os.system(prefix+" "+f) # execute each line with the given prefix.
Hope it helps.