I have a variable that can contain string and/or number but in some case i have to remove numeric characters. So i am basicly;
if defined ARG2 (
for %%b in (0 1 2 3 4 5 6 7 8 9) do set ARG2=!ARG2:%%b=!
)
It works almost all cases but there is a problem. If ARG2 contain nothing but numeric characters its changing ARG2 value to something like 9= . How can i fix this issue or is there a better way to remove numeric characters from variable?
When inputting 888 your for loop will reach 8 and remove all characters from the string. Therefore you have an empty variable. So when you try to remove 9 it expands to nothing, then for some reason (not entirely sure why) cmd doesn't consider the string manipulation, and just displays it (similarly 666 will output 7= and so on). To fix this you simply need to add a check, to see if ARG2 is empty or not.
if defined ARG2 (
for %%b in (0 1 2 3 4 5 6 7 8 9) do if "!ARG2!"=="" ( goto :break ) else set ARG2=!ARG2:%%b=!
)
:break
This will just goto the :break label if ARG2 expands to nothing.
The answers here - How does the Windows Command Interpreter (CMD.EXE) parse scripts? - should give some better explanation of why.
Related
Here is my sample batch file code and I really don't know what it does.
set TEMPRPSW=%RPSW_VERSION%
set RELVER=%TEMPRPSW:~0,4%
set RELVER=%RELVER:.=%
if %RELVER% GEQ 30 goto :eof
Please give me a working sample.
That takes a 4 character long substring of TEMPRPSW, starting from character 0.
Meaning, it takes the first 4 characters of TEMPRPSW and puts them in RELVER.
set TEMPRPSW=abcdef
set RELVER=%TEMPRPSW:~0,4%
echo %RELVER% -> will print abcd
%VAR:str=% removes str
set RELVER=123.456
set RELVER=%RELVER:.=%
echo %RELVER% -> will print 123456 with no .
here is a nice article: https://www.dostips.com/DtTipsStringManipulation.php
This question already has an answer here:
Windows batch file IF failure - How can 30000000000000 equal 40000000000?
(1 answer)
Closed 5 years ago.
I have a very silly issue but unable to figure out what is wrong
I'm doing a basic level number comparison in if statement. script is pasted below. geq-greater than or equal to is working fine but gtr-greater than has a problem. Is there any limitation for numbers in gtr comparison?
if 3 gtr 2 (#echo "greater") else (#echo "lesser")
greater
if 3 geq 2 (#echo "greater") else (#echo "lesser")
greater
if 135149772801 gtr 111110000000 (#echo "greater") else (#echo "lesser")
lesser
if 135149772801 geq 111110000000 (#echo "greater") else (#echo "lesser")
greater
Is there any limitation for numbers in gtr comparison?
Yes, there really is.
You're limited to 32-bit signed integers and, if there's overflow, it's set to the maximum value.
Since both those numbers, 135149772801 and 111110000000, are too big, they're both converted to 231 - 1.
That's why it says the first is not greater (which is subtly different to lesser, by the way) but it is greater than or equal to.
More details can be found at the excellent dostips site.
A way around the 32-bit limit is to prefix the numeric-string with a goodly number of 0 and then use an alphabetic comparison on the last n characters.
Hence
set "num1=135149772801"
set "num2=111110000000"
set "zeroes=00000000000000000000000000000000000000000000000000000"
set "comp1=%zeroes%%num1%"
set "comp2=%zeroes%%num2%"
if "%comp1:~-20%" gtr "%comp2:~-20%" (echo greater) else (echo not greater)
where "-20" above means "take the last 20 characters"
A batch-file natively supports 32-bit signed integer arithmetic only. If the number goes over 2147483648, it overflows and warp back to negative number. However in if statements, the number gets clutter back to 2^31-1.
Code | Code Result | Actual Result
-----------------------+-------------------+-----------------------
2147483647 + 1 2147483648 2147483648
2147483648 + 1 -2147483648 2147483649
Here is some possible workaround:
Chopping the number(making the number smaller before comparing)
Other scripting languages(use powershell or vbs to compare)
Embedded Powershell solution:
for /f %p in ('powershell -command if (1 -gt 0^) {write-host greater} else {write-host lesser}') do echo %p
This command calls powershell to compare, and retrieve the results using a for loop.
I found some sample code but I am unable to get what this if condition means:
set /p sourceDB=Enter Source DB: %=%
set S=%sourceDB%
set I=0
set L=-1
:l ----- Forget about this line
if "!S:~%I%,1!"=="" goto ld
if "!S:~%I%,1!"=="/" set K=%I%
if "!S:~%I%,1!"=="#" set Z=%I%
if "!S:~%I%,1!"==":" set Y=%I%
set /a I+=1
goto l
The short answer is that this is how you get substrings in batch.
When you extract a substring, you use the format %string_name:~index_of_first_character_in_substring,length_of_substring% or, if the value of either index_of_first_character_in_substring or length_of_substring is contained in a separate variable (in your example, the index is its own variable), you can enable delayed expansion and use the format !string_name:~%variable_whose_value_is_the_index_of_first_character_in_substring%,length_of_substring!
In this case, your main string is in a variable called %S%, you are starting at character %I%, and grabbing 1 character.
The line you've told us to ignore is actually pretty important, as it's used to loop through the entire string.
The entire line "!S:~%I%,1!"=="" is used to check if the substring is empty -- that is, the script is finished iterating through the string. There are also conditions for if the substring is /, #, and :; with K, Z, and Y respectively containing the indices of those substrings.
using dos commands how can I match substring from a variable.
e.g: var="Lost = 0 (0% loss)"
I want to check whether var contains "Lost" in it.
I have already tried Contains, like but throwing error.
echo %varname%|findstr "string" >nul
if errorlevel 1 (echo %varname% does not contain "string"
) else (echo %varname% contains "string")
Note that this can all be on one line if you prefer. If broken across lines, the sequence ) else ( must be on same line, as must the if and very first (
I was testing this code submitted by unclemeat in this question(UncleMeat referenced this site) when I tested it by inputting some carots(^) it produced some interesting results.
Len.bat
#echo off
setLocal EnableDelayedExpansion
set s=%1
set length=0
:count
if defined s (
set s=%s:~1%
set /A length += 1
goto count
)
echo %length%
Testing of Len.bat
C:\Users\Public>len ^
More?
More?
0
C:\Users\Public>len ^^
12
C:\Users\Public>len ^^^
More?
More?
12
C:\Users\Public>len ^^^^
1
C:\Users\Public>len ^^^^^
More?
More?
1
C:\Users\Public>len ^^^^^^
13
C:\Users\Public>len ^^^^^^^
More?
More?
13
C:\Users\Public>len ^^^^^^^^
22
C:\Users\Public>
Ignoring the double More? where I simply returned without inputting anything, the pattern is:
0
12
12
1
1
13
13
22
22
13
13
2
2
14
14
23
23
14
14
23
23
14
14
23
23
Every odd occurance prompts me with the double More?, which is why it is doubled, but other wise these results are just wierd. I thought it would have to do something with the following line in the code, but there seems to be no relationship!
Any explanation to this irregular data? Or is this just one of those things about cmd....
It has many reasons why the code completly fails with carets.
First the way you try to call your batch will fail.
A caret escapes the next character and is itself removed from the line.
A single caret at a line end escapes the line end (it's called multiline caret), that's the cause why cmd.exe show you the prompt More?.
This will be true for all odd number of carets.
Sample with seven carets.
length ^^^^^^^
More?
More?
cmd.exe will call the length bat with the following string ^^^<newline>.
The newline will be split from the %1 parameter, so in %1 is only ^^^.
But now you this part fails completly
set s=%1
set length=0
As it expands to
set s=^^^
set length=0
As the last caret is now a multiline caret it will append set length=0 to the line!
So in the variable s is now the content ^set length=0.
This will never work ...
Even in this block the %s:~1% will be a cause of further problems, as it will also can expand to multiline carets when s contains carets (when you use 8 carets length ^^^^^^^^).
if defined s (
set s=%s:~1%
set /A length += 1
goto count
)
For some more explanations about the caret you can read
SO:Long commands split over multiple lines in Vista/DOS batch (.bat) file