I try to get all data included in [] (not specific tokens!)
I try with loop but its give only 1 parameter.
Example what I need:
set "x=Stackoverflow [I need it] and [I need this too] and [this too]"
output => I need it, I need this too, this too
Tried to do:
for /f "delims=[]" %%a in ("%x%") do (
echo %%a
)
you could use "tokens=2,4,6,8,10,12 delims=[]", but it is difficult to post-process the result (removing additional commas/spaces).
The same effect can be reached by preprocessing the string and splitting with a plain for loop. The flag variable takes care of using each second token only. I added a _ in front of the string to correctly process strings that start with a [. set /a "flag=(flag+1) %% 2" alternates the flag variable between 0 and 1.
#echo off
setlocal enabledelayedexpansion
set "x=[this] not [that] not [yes] no [in] out"
set "y=_%x:[=","%"
set "y=%y:]=","%"
set flag=0
for %%a in ("%y%") do (
if !flag!==1 set "result=!result!, %%~a"
set /a "flag^=1"
)
if defined result set "result=%result:~2%"
echo output = %result%
Output:
output = this, that, yes, in
A very simple method:
#echo off
setlocal EnableDelayedExpansion
set "x=Stackoverflow [I need it] and [I need this too] and [this too]"
set "output=" & set "p=%x:]=" & set "output=!output!, !p:*[=!" & set "p=%"
echo output =^> %output:~2%
Output:
output => I need it, I need this too, this too
For an explanation of the method used, you should remove the #echo off line, run the program and carefully review the executed code. If you want further explanations, then review this topic.
Related
I have a string
<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>
I am trying to trim out DA7C36F0-A749-4CC5-9575-398C06039325 from this line.
To begin with I tried to set this string in a variable but I am not able to do that may be because of < and ? in string, I tried:
set "var=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
But later I was able to fetch the string somehow at runtime and now I have the variable
line=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>
I am not able to figure out how can I trim only value i.e DA7C36F0-A749-4CC5-9575-398C06039325 out of this variable using batch script.
I gave it a try to trim suffix at least with:
set "line=%line:"?>%"
But getting error, can anyone help with better approach?
Note: the spaces are included in string
You can split the string using " as a delimiter, but since quotes are used to specify for loop options, the syntax looks a little different than usual:
#echo off
setlocal enabledelayedexpansion
set "line=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
echo !line!
for /f tokens^=2^ delims^=^" %%A in ("!line!") do set "line=%%A"
echo !line!
You may use this very simple trick:
#echo off
setlocal EnableDelayedExpansion
set "var=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
set "i=0" & set "v0=%var:"=" & set /A i+=1 & set "v!i!=%"
echo Desired string: [%v1%]
If you want to know how this works, remove the #echo off line and carefully review what appears in the screen...
Your command line:
set "line=%line:"?>%"
does not make sense, because there is an =-sign missing (refer to sub-string substitution):
set "line=%line:"?>=%"
To trim away the unwanted prefix you could remove everything up to the first quotation mark:
set "line=%line:*"=%"
However, this only works when you do that after having removed the suffix, because you are dealing with unbalanced quotation marks, which are problematic together with immediate variable expansion. If you want to change the order, you have to implement escaping in order not to exhibit the redirection operator > unquoted:
set ^"line=%line:*"=%"
set "line=%line:"?>=%"
To avoid the need of escaping depending on the input string, use delayed variable expansion, like this:
set "line=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
set line
rem // First enable delayed expansion:
setlocal EnableDelayedExpansion
rem // Then apply it by replacing `%` with `!`:
set "line=!line:*"=!"
set "line=!line:"?>=!"
set line
rem // This restores the previous state:
endlocal
rem // At this point changes in the variable are no longer available due to localisation:
set line
I want to concatenate the string in the array inside the for loop. Once it get concatenate it should do some task and then it go to the another variable in the array. Please let me know how to do it. Give me some examples.
Here is the code I am trying to execute.
#echo off
set topic[0]=USB
set topic[1]=hello
set topic[2]=mic
set topic[3]=Operators
set file = C:\Users\User\Android_Studio_Projects
for /l %%n in (0,1,2) do (
set file=%file% CD\!topic[%%n]!
)
pause
You need to be carefull of whitespace before and after = when setting variables, also, to use delayedexpansion, you need to enable it. You are also trending on the line with whitespace in setting variables, always enclose your variable set in double quotes, like I did below. Try this:
#echo off
setlocal enabledelayedexpansion
set "topic[0]=USB"
set "topic[1]=hello"
set "topic[2]=mic"
set "topic[3]=Operators"
set "file=C:\Users\User\Android_Studio_Projects\"
for /l %%n in (0,1,3) do (
echo cd %file%!topic[%%n]!
)
pause
You do not need to set %file% again inside of the loop seeing that nothing changed. This will only display the command to you, to cd to each directory, just remove echo in the loop.
I'm trying to set up a batch menu that allows for multiple selection at once then runs all the functions. Sequence that functions are not relevant just the fact that the functions will be run with out, outside errors. Here is the code that I have so far.
#Echo off
Echo Please Enter the corrasponding numbers separated by a space or colon (,)
Echo for the Options that you would like to run e.g. 1 4,3 2
Echo Option #1
Echo Option #2
Echo Option #3
Echo Option #4
Echo.
SET /P Selection=Please Select Restore Options?
echo You chose: %Selection%
setlocal ENABLEDELAYEDEXPANSION
Set /a index = 0
FOR %%A IN (%Selection%) DO (
SET Array[!index!] = %%A
SET /a index += 1
)
for /F "tokens=2 delims==" %%s in ('set Array[') DO (
set string=%%s
set string=%string: =%
echo %string%
Call :Opt%string%
)
pause
goto :EOF
:Opt1
ECHO Option 1's code
GOTO :EOF
:Opt2
ECHO Option 2's code
GOTO :EOF
:Opt3
ECHO Option 3's code
GOTO :EOF
:Opt4
ECHO Option 4's code
GOTO :EOF
The code I have works to the point where trying to call the Array veriable and attach it to a Call e.g. Call :Opt%%s
The probelm I have is that the array variable keeps coming out with a space proceeding the selected variable. So I have tried combating this with set string=%string:=% but I keep getting an error.
Error :
either echo is off and only opt is getting called with out the selected variable.
Help with this would be amazing, Thanks in advance.
The start of the problems is
SET Array[!index!] = %%A
------------------^-^---- = aditional spaces
This aditional spaces are used, so you end with a variable with an aditional space in its name and an aditional space in its value. So, better use
SET "Array[!index!]=%%A"
The reason for the echo error is you forget to use delayed expansion in the for %%s loop. You change the %string% variable inside the loop and try to use the changed value inside the same loop.
for /F "tokens=2 delims==" %%s in ('set Array[') DO (
set "string=%%s"
set "string=!string: =!"
echo !string!
Call :Opt!string!
)
But the corrections indicated in the original set make it unnecessary to replace the spaces.
MC ND solved most of the problems with your code.
One trivial issue - the punctuation is a comma, not a colon ;-)
But a more serious issue, what if the user entered 3 choices, and there already was a variable named Array[4]? It would run that extra value that hadn't been entered by the user. It would even attempt to run a value stored in Array[anythingGoes.
You've got the number of values stored in "index", so why not use it? A more common and simpler way to iterate the array is to use a FOR /L loop. This also preserves the original order. Your way would change the order once you get 10 or more entries. (I know you say order doesn't matter, but why change the order if you don't have to?)
setlocal enableDelayedExpansion
for /l %%N in (1 1 %index%) do (
echo !Array[%%N]!
call :Opt!Array[%%N]!
)
But I don't see a reason to mess with an array at all. Your loop that parses the user input could simply call the functions directly. Now you don't even need delayed expansion.
for %%A in (%Selection%) do (
echo %%A
call :Opt%%A
)
Am trying to read characters of a string inside a for loop.
The command !string:~1,3! works fine. But can I do this with variables instead of 1 and 3. I tried the following code, but I don't know what is wrong. Its not working.
#echo off
setlocal enableextensions enabledelayedexpansion
set string=abcdefghij
set /a count=1
for /l %%x in (1,1,3) do (
set string2=!string:~%count%,1!
set /a count+=1
echo !string2!
pause
)
but It always gives the output as:
b
I want the output to be as:
b
c
d
Kindly help in solving this.. A big thanks in advance
In order to achieve what you want, you need to do a Delayed Expansion twice, that is, something like this:
set string2=!string:~!count!,1!
Of course, previous line is invalid. Although there are several ways to solve this problem, most of they use call command that is slow. To fix this problem so it run in the fastest way use a for command to change the first !count! expansion into a FOR replaceable parameter, and then use it in the original expression:
for %%i in (!count!) do set string2=!string:~%%i,1!
The problem is that the expansion of %count% isn't delayed, so it has the same value for every loop iteration. It's better written like this:
#echo off
setlocal enableextensions enabledelayedexpansion
set string=abcdefghij
set /a count=1
for /l %%x in (%count%,1,3) do (
set string2=!string:~%%x,1!
echo !string2!
)
Edit
If you want to keep %count% evaluated as the variable is set and not just at the beginning of the for loop, use Aacini's answer.
I've a text file with two rows (say param.txt) which is shown below:
Mar2012
dim1,dim2,dim3,dim4
I want to read this file in batch and store the contents of first line in a variable called cube_name. When I'm reading the second line, I want to split the comma delimited string dim1,dim2,dim3,dim4 and create an array of four elements. I am planning to use the variable and the array in later part of the script.
The code which I created is shown below. The code is not working as expected.
#echo off & setlocal enableextensions enabledelayedexpansion
set /a count_=0
for /f "tokens=*" %%a in ('type param.txt') do (
set /a count_+=1
set my_arr[!count_!]=%%a
)
set /a count=0
for %%i in (%my_arr%) do (
set /a count+=1
if !count! EQU 1 (
set cube_name=%%i
)
if !count! GTR 1 (
set dim_arr=%%i:#=,%
)
)
for %%i in (%dim_arr%) do (
echo %%i
)
echo !cube_name!
I get to see the following when I run the code:
C:\Working folder>test2.bat
ECHO is off.
So this doesn't appear to work and I can't figure out what I'm doing wrong. I am fairly new to the batch scripting so help is appreciated
Your first FOR loop is OK. It is not how I would do it, but it works. Everything after that is a mess. It looks like you think arrays are a formal concept in batch, when they are not. It is possible to work with variables in a way that looks reminiscent of arrays. But true arrays do not exist within batch.
You use %my_arr% as if it is an array, but my_arr is not even defined. You have defined variables my_arr[1] amd my_arr[2] - the brackets and number are part of the variable name.
It also looks like you have a misunderstanding of FOR loops. I suggest you carefully read the FOR documentation (type HELP FOR from a command line). Also look at examples on this and other sites. The FOR command is very complicated because it has many variations that look similar to the untrained eye, yet have profoundly different behaviors. One excellent resource to help your understanding is http://judago.webs.com/batchforloops.htm
Assuming the file always has exactly 2 lines, I would solve your problem like so
#echo off
setlocal enableDelayedExpansion
set dimCnt=0
<param.txt (
set /p "cube_name=" >nul
set /p "dimList=" >nul
for %%D in (!dimList!) do (
set /a dimCnt+=1
set "dim[!dimCnt!]=%%D"
)
)
echo cube_name=!cube_name!
for /l %%I in (1 1 !dimCnt!) do echo dim[%%I]=!dim[%%I]!
One nice feature of the above solution is it allows for a varying number of terms in the list of dimensions in the 2nd line. It will fail if there are tabs, spaces, semicolon, equal, * or ? in the dimension names. There are relatively simple ways to get around this limitation if need be.
Tabs, spaces, semicolon and equal can be handled by using search and replace to enclose each term in quotes.
for %%D in ("!dimList:,=","!") do (
set /a dimCnt+=1
set "dim[!dimCnt!]=%%~D"
)
I won't post the full solution here since it is not likely to be needed. But handling * and/or ? would require replacing the commas with a new-line character and switching to a FOR /F statement.
I'm impressed of your code!
Do you try to debug or echo anything there?
You could simply add some echo's to see why your code can't work.
#echo off & setlocal enableextensions enabledelayedexpansion
set /a count_=0
for /f "tokens=*" %%a in ('type param.txt') do (
set /a count_+=1
set my_arr[!count_!]=%%a
)
echo ### show the variable(s) beginning with my_arr...
set my_arr
echo Part 2----
set /a count=0
echo The value of my_arr is "%my_arr%"
for %%i in (%my_arr%) do (
set /a count+=1
echo ## Count=!count!, content is %%i
if !count! EQU 1 (
set cube_name=%%i
)
if !count! GTR 1 (
echo ## Setting dim_arr to "%%i:#=,%"
set dim_arr=%%i:#=,%
echo
)
)
for %%i in (%dim_arr%) do (
echo the value of dim_arr is "%%i"
)
echo cube_name is "!cube_name!"
Output is
### show the variable(s) beginning with my_arr...
my_arr[1]=Mar2012
my_arr[2]=dim1,dim2,dim3,dim4
Part 2----
The value of my_arr is ""
cube_name is ""
As you can see your part2 fails completly.