0

Below is the code I am working on

setlocal enabledelayedexpansion
echo on

IF NOT EXIST "D:\Deployments\Parameter_Build*.txt" (
exit
)
set SCRIPTDIRECTORY=D:\Deployments\
PUSHD %SCRIPTDIRECTORY%
FOR %%A in (Parameter_Build*.txt) DO (
echo %%A

set ANT_HOME=C:\tibco\ant\apache-ant-1.9.13
set string=
set /p string=< D:\Deployments\%%A
echo string is !string!
echo before for loop
call :myInnerloop !string!

 )
POPD
GOTO:EOF

rem *************************************************************

:myInnerloop
FOR /F "tokens=2,4,6,8,10 delims==:" %%G IN ("!string!") DO (
echo inside for loop
set COMPONENTDIR="D:\kpn_eai\EAI_FIXED\branches\kpn_eai_fixed\fixed\components"
set CONFIGDIR="D:\kpn_eai\EAI_FIXED\branches\kpn_eai_fixed\fixed\configuration\components"
set ADAPTER=%%K

echo %%G %%H %%I %%J %%K

echo value taken from file is !string! >> D:\Deployments\logs\Deployment-%%J.log 2>&1
svn update !COMPONENTDIR!\!ADAPTER! >> D:\Deployments\logs\Deployment-%%J.log 2>&1
svn update !CONFIGDIR!\!ADAPTER! >> D:\Deployments\logs\Deployment-%%J.log 2>&1


echo Starting with deployment with parameters %%G %%H %%I >> D:\Deployments\logs\Deployment-%%J.log 2>&1
%ANT_HOME%\bin\xanteai deploy %%G %%H %%I >> D:\Deployments\logs\Deployment-%%J.log 2>&1
echo Deployment completed >> D:\Deployments\logs\Deployment-%%J.log 2>&1
move D:\Deployments\Parameter_Build-%%J.txt D:\Deployments\archive\Parameter_Build-%%J.txt
RENAME D:\Deployments\logs\Deployment.txt Deployment-%%J.log

 )
:next
GOTO:EOF



endlocal

Parameter_Build file contains text in below format :-

Environment=:Domain=:Component=xyz.zip|abc.zip|jkl.zip|efg.zip:Build=160:Adapter=xyz|abc|jkl|efg

Here I am trying to perform deployment for each Component

Component=xyz.zip|abc.zip|jkl.zip|efg.zip

by taking SVN update for each Adapter

xyz|abc|jkl|efg

I need to separate Component and Adapter consecutively and pass it to deploy command one by one. Also before triggering deployment I need to use each components respective adapter for taking SVN update (for eg: If component xyz.zip is triggered for deployment Adapter xyz should get updated first by SVN Update utility)

acroniks
  • 99
  • 7
  • oops sorry, I misread batch for bash.. :) – Nikos M. Apr 01 '19 at 10:44
  • Using `for` That is the only way you can create metavariables. Why don't you want to use a `for` loop when it is designed to do this? – Gerhard Apr 01 '19 at 10:45
  • 2
    It's possible, but what's the problem with `FOR /F`? – jeb Apr 01 '19 at 10:51
  • @jeb creating metavariables without for loop? Please show me.. :) – Gerhard Apr 01 '19 at 10:53
  • 2
    @GerhardBarnard The point is to tokenize a string witthout FOR, I don't try to create metavariables like `%%X`. – jeb Apr 01 '19 at 11:02
  • @jeb ah ok, I thought you meant to create metavariables without `for` :) – Gerhard Apr 01 '19 at 11:35
  • @Gerhard Barnard Actually i have two for loops for my code(1st for loop driving the whole code and inner code used for deployments) and adding one more for loop is making it cumbersome for me to understand in batch. I am calling second loop from inside of 1st loop `(call :myInnerloop !string!)` – acroniks Apr 01 '19 at 11:58
  • But trying the same for third for loop is not working for me. So i thought of resorting to this way of not using for loop. – acroniks Apr 01 '19 at 12:01
  • Possible duplicate of [How to print value of a specific item in an array in batch file, without looping?](https://stackoverflow.com/questions/45491838/how-to-print-value-of-a-specific-item-in-an-array-in-batch-file-without-looping) –  Apr 01 '19 at 12:03
  • Why not share the code you have as is, then I/we can simply make it simpler for you? – Gerhard Apr 01 '19 at 12:03
  • @GerhardBarnard Shared the code above. – acroniks Apr 01 '19 at 12:34
  • So what exactly do you want to extract? just seperate instances of `xyz` `abc` `jkl` and `efg`? – Gerhard Apr 01 '19 at 12:43
  • so I basically need to see what your expected results should be. – Gerhard Apr 01 '19 at 12:47
  • Yes i want to separate them and trigger deployment for each Component. Also before triggering deployment i need to use each components respective adapter for taking SVN update (for eg: If component xyz.zip is triggered for deployment Adapter xyz should get updated first by SVN Update utility). Are my expectations clear? – acroniks Apr 01 '19 at 12:48
  • ok, I suggest you edit the question again, remove unwanted items, leave the script and input, and show the expected results exactly please. Show me exactly from the input, what you require to be the output. – Gerhard Apr 01 '19 at 12:51
  • `set "string=xyz.zip|abc.zip|jkl.zip|efg.zip"`, `echo "%string:.zip=%"` – Stephan Apr 01 '19 at 12:52

2 Answers2

4

This creates the variables a[0], a[1], ... a[n]

@echo off

setlocal EnableDelayedExpansion
set "var=xyz|abc|jkl|efg"

set cnt=0
set "a[0]=%var:|="&set /a cnt+=1&set "a[!cnt!]=%"

echo cnt=!cnt!
set a[

Output:

cnt=3
a[0]=xyz
a[1]=abc
a[2]=jkl
a[3]=efg

Explanation

The code simply replaces all occurences of the delimiter with "&set /a cnt+=1&set "a[!cnt!]=.
That looks strange but as example it looks like

set "a[0]=xyz"  & set /a cnt+=1  & set "a[!cnt!]=abc"  & set /a cnt+=1  & set "a[!cnt!]=jkl"  & set /a cnt+=1  & set "a[!cnt!]=efg"

When unrolled to multiple lines it looks like

set "a[0]=xyz"  
set /a cnt+=1  
set "a[!cnt!]=abc"  
set /a cnt+=1  
set "a[!cnt!]=jkl"  
set /a cnt+=1  
set "a[!cnt!]=efg"

In other words, it creates several commands per one delimiter.

This technic can be used even with string delimiters like <->

set "a[0]=%var:<->=...

Thanks to @Aacini, who introduced this technic, see split string into substrings based on delimiter

jeb
  • 78,592
  • 17
  • 171
  • 225
  • 2
    Although unlikely, it would be prudent to ensure that there's no predefined variables in the environment beginning with `a[`. This of course uses a `For` loop, which may conflict with the OP's anti-for loop stipulation, but would look something like this: `For /F "Delims==" %%A In ('Set a[ 2^>Nul')Do Set "%%A"`. – Compo Apr 01 '19 at 11:11
  • 1
    @jeb Is it possible for you to explain how it works?? – acroniks Apr 01 '19 at 11:54
  • @UtkarshMishra, there was a link provided in the last line of the answer above, where the method was explained over three pages, please read it in it's entirety! – Compo Apr 01 '19 at 12:42
  • @UtkarshMishra: For a simple explanation of this method, see [this comment](https://stackoverflow.com/questions/23600775/split-string-with-string-as-delimiter/33131797#comment93049961_33131797) at another similar answer that uses the same method... – Aacini Apr 01 '19 at 13:45
  • @jeb: I like the explanation! **`:)`** – Aacini Apr 01 '19 at 13:53
1

I still don't understand what you really want to do, but perhaps this may help you:

@echo off
setlocal

set "Component=xyz.zip|abc.zip|jkl.zip|efg.zip"

for %%a in ("%Component:|=" "%") do (
   echo With extension: %%~a
   echo Without extension: %%~Na
)

EDIT: New method added

Please, review this code:

@echo off
setlocal EnableDelayedExpansion

rem Parameter_Build file contains text in below format :-
rem Environment=:Domain=:Component=xyz.zip|abc.zip|jkl.zip|efg.zip:Build=160:Adapter=xyz|abc|jkl|efg

rem Read the file:
set /P "line=" < Parameter_Build.txt
echo Line read:
echo !line!

rem Separate variables:
set "%line::=" & set "%"

rem Separate Component and Adapter in *matching* parts
set cnt=1
set "Component[1]=%Component:|=" & set /A cnt+=1 & set "Component[!cnt!]=%"
set cnt=1
set "Adapter[1]=%Adapter:|=" & set /A cnt+=1 & set "Adapter[!cnt!]=%"

rem Ok:
for /L %%i in (1,1,%cnt%) do echo Component[%%i]=!Component[%%i]!, Adapter[%%i]=!Adapter[%%i]!

Output example:

Line read:
Environment=:Domain=:Component=xyz.zip|abc.zip|jkl.zip|efg.zip:Build=160:Adapter=xyz|abc|jkl|efg
Component[1]=xyz.zip, Adapter[1]=xyz
Component[2]=abc.zip, Adapter[2]=abc
Component[3]=jkl.zip, Adapter[3]=jkl
Component[4]=efg.zip, Adapter[4]=efg
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Deployment in my case is done by below line `%ANT_HOME%\bin\xanteai deploy %%G %%H %%I` in which %%I is component name. In the file Parameter_Build it is possible to have many components separated by pipe. Just need to pick one adapter at a time and pass it to command above. So that the script can perform deployment. – acroniks Apr 01 '19 at 13:59
  • But using one more for loop in my code to pick one component from pipe separated %%I components is not working for me. – acroniks Apr 01 '19 at 14:04
  • Please, check my edit. If it still is not what you want, please, explain it much more clearly... – Aacini Apr 01 '19 at 14:16
  • Your code is working fine. But if you go through my code you will notice few things like first **FOR loop** `FOR %%A in (Parameter_Build*.txt) ` checks availability of file in the directory, if file is available it will pass the file name to %%A and then from that it will read the parameters. Second **FOR loop** picks up parameters tokenize it and use those Tokenized parameters at different places like SVN update and Ant Deploy. Issue I am facing is I am not able to run the whole code if I am introducing one more **FOR loop** – acroniks Apr 01 '19 at 15:08
  • I tried embedding your code into my code but it is not running as expected. Your code is running fine if I remove all of my code and run only **Your Code** solely. – acroniks Apr 01 '19 at 15:12
  • Also Second **FOR loop** is tokenizing the parameters on basis of delim ":" , And as per my requirement I may require to add one more Third **FOR loop** in order to tokenize Component and Adapter on basis of delim "|" . But the question is how? – acroniks Apr 01 '19 at 15:15
  • I don't understand your concerns. You may check file availability via `if exist` command. Anyway, I don't see the problem of insert any number of nested `for` commands if they are required... I am *not* reading your code and attempt to fix it (it have a lot of lines unrelated to this problem), so I don't understand what you mean with `%%G` or `%%H`... I could present a solution if you describe the desired output (commands) based on input file. Please, don't use any "SVN" terms! I think a simple `echo` command is enough... – Aacini Apr 02 '19 at 13:39
  • I figured out why I was not able to use third for loop. It was because while reading Component Parameter from file some how pipe separated fields are not allowing the code to enter the for loop. I replaced pipe with "~" and it is working fine for me now. – acroniks Apr 03 '19 at 08:04