I have the following string:
9/14/22 11:00:12,,,0,0,,,,,,
I need to remove 9/14/22 11:00:12 so I only have ,,,0,0,,,,,, left over.
#echo off
set str=9/14/22 11:00:12,,,0,0,,,,,,
FOR /F "tokens=1* delims=," %%a in ("%str%") DO (
set REMOVE_STR=%%a
)
set REMAINING_STR=%str:;%REMOVE_STR%;=%
echo New string: %REMAINING_STR%
The output is just the original string, so I know there's a problem with the substr removal step. But, I can't figure out what I'm doing wrong.
You need delayed expansion to use variables inside a code block that you defined/changed within the same block:
#echo off
setlocal enabledelayedexpansion
set str=9/14/22 11:00:12,,,0,0,,,,,,
FOR /F "tokens=1 delims=," %%a in ("%str%") DO (
set "remaining_str=!str:%%a=!"
echo New string: !Remaining_Str!
)
Output:
New string: ,,,0,0,,,,,,
You don't need a for loop, or delayed expansion for that task, you can do it with direct variable expansion and sustitution, just like this:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "str=9/14/22 11:00:12,,,0,0,,,,,,"
Set "REMAINING_STR=,%str:*,=%
Echo New string: %REMAINING_STR%
The above substitutes everything up to, and including, the first comma, with nothing, in the expanded variable, and precedes that with the initially first removed comma.
You could alternatively substitute everything up to, and including, the first comma, with a comma, like this:
Set "REMAINING_STR=%str:*,=,%
Related
I have a parameter string read from a properties file. One of the properties is as below:
"CUSTOM_JAVA_OPTIONS=-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080"
I need to split this string on the first occurrence of "=" and set a parameter with the value:
-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080
I am trying to split the string first on the = token and then remove the fist sub-string token from the original string.
In the below code %%G will be set to "CUSTOM_JAVA_OPTIONS" and I am trying to remove this from the original string "TESTSTR"
#echo off
set "TESTSTR=CUSTOM_JAVA_OPTIONS=-Dhttp.proxyHost=webcache.example.com
-Dhttp.proxyPort=8080"
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=1,2 delims==" %%G IN ("%TESTSTR%") DO (
echo Name=%%G
echo Value=%%H
set removestr=%%G
echo TESTSTR=!TESTSTR!
echo removestr=!removestr!
set "str=!TESTSTR:%removestr%=!"
echo str=!str!
)
pause
The above does not seem to work, it produces:
Name=CUSTOM_JAVA_OPTIONS
Value=-Dhttp.proxyHost
TESTSTR=CUSTOM_JAVA_OPTIONS=-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080
removestr=CUSTOM_JAVA_OPTIONS
str=TESTSTR:=
Expected result needs to be:
str=-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080
This could be simplified to:
#echo off
set "TESTSTR=CUSTOM_JAVA_OPTIONS=-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080"
FOR /F "tokens=1* delims==" %%G IN ("%TESTSTR%") DO set "str=%%H"
echo TESTSTR=%TESTSTR%
echo.str=%str%
pause
There are 2 tokens:
1. Text up to 1st delimiter
2. Everything else after first delimiter (*)
Note that by echoing the variables outside of the FOR loop you don't need to enable delayed expansion.
Your code fails entirely because %removestr% is expanded when the command is initially parsed, and your entire loop (code block) is parsed all at once. So %removestr% expands to the value that existed before your loop was entered. In your case, the variable is undefined. So !TESTSTR:%removestr%=! becomes !TESTSTR:=!, which finally becomes TESTSTR:=.
You get closer if you use %%G directly, instead of assigning an environment variable.
set str=!TESTSTR:%%G=! yields =-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080
You can then use set str=!str:~1!" to remove the leading =.
set str=!TESTSTR:%%G==! will not work because the search strings stops at the first occurrence of =, so the result is ==-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080
The RGuggisberg answer is the most convenient method to get your desired result. (You may want both %%G and %%H).
However, it technically does not break at the first =. It actually breaks at the first string of contiguous = because FOR /F does not parse empty tokens.
So for /f "tokens=1* delims==" %%G in ("A==B==C") yields A for %%G (correct), and B==C (incorrect) for %%H. The correct value should be =B==C.
If the first character after the = character is always a -, then the following method may also work for you:
#Echo Off
Set "TESTSTR=CUSTOM_JAVA_OPTIONS=-Dhttp.proxyHost=webcache.example.com -Dhttp.proxyPort=8080"
Set "REST=-%TESTSTR:*-=%"
Set "FIRST=%TESTSTR:-="&:"%"
Set "FIRST=%FIRST:~,-1%"
Echo [%FIRST%] [%REST%] & Pause
The bottom line is simply to show you the information.
This is the very first time i tried batch scripting so please bear with me.
I just wanted to read each line of my hosts file, and replace the line if it contains/matches a substring. I've seen a lot of answered questions about substrings here but I just can't make it work by using the provided solutions.
I have this code:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "hostspath=%SystemRoot%\System32\drivers\etc\hosts"
set "hostsbackuppath=c:\hosts"
>"%hostsbackuppath%.new" (
rem Parse the hosts file, skipping the already present hosts from our list.
rem Blank lines are preserved using findstr trick.
for /f "delims=: tokens=1*" %%a in ('%SystemRoot%\System32\findstr.exe /n /r /c:".*" "%hostspath%"') do (
set str1=%%b
if not x!str1:mydomainname=!==x!str1! (
rem Match found, replace this line.
echo "match!"
set matched=false
)
// Didn't match, do not replace
if not "!matched!"=="true" echo.%%b
)
)
I was trying out this solution to check for substring match among other else: Batch file: Find if substring is in string (not in a file)
Can someone help me? Thanks
SETLOCAL ENABLEDELAYEDEXPANSION
set "matched=true"
>"%hostsbackuppath%.new" (
for /f "delims=: tokens=1*" %%a in ('%SystemRoot%\System32\findstr.exe /n /r /c:".*" "%hostspath%"') do (
set "str1=%%b"
if not "!str1:mydomainname=!"=="!str1!" (
rem Match found, replace this line.
echo "match at %%b in line %%a"
set matched=false
)
// Didn't match, do not replace
if not "!matched!"=="true" echo.%%b
)
)
Hooley-dooley! Someone needs to learn to name variables appropriately.
First, you need to use setlocal enabledelayedexpansion - please see a thousand-and-one SO articles about delayed expansion.
Since str1 is varied within the loop, you need to use setlocal enabledelayedexpansion and !var! to access the varying value of var as %var% is the value at the time the for was encountered.
The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. set /a can safely be used "quoteless".
FOr the same reason, quoting each side of a comparison is preferred as it makes a single token of a string containing separators like spaces.
Then you have a comment "match found" after which you set matched to false ?? Therefore you need to initialise match (to true)
Now quite what you want to do is obscure. On re-reading, you probably want to set "matched=true" as the first line within the loop, not outside as I have it, so that the value is re-set to true for each line found and then set to false if a match is found.
All this negative logic is insane. I need a strong cup of coffee.
I am trying to find the following version number in a app.config file.
The file is XML format.
Line 8 in the file (Adding line in again as the greater/less than symbols were stripped from the post initially)
add key="ReleaseVersion" value="5.2.0.2"
I been using various FOR /F commands, have been close a couple of times.
However I have not been able to extract the 5.2.0.2 value and use as a variable
so far in my script.
Additionally while I am looking for this value 5.2.0.2, going forward the version number will change so I am not looking for a exact match e.g. "5.2.0.2", I am looking to capture what is in the inverted commas e.g. value="", and then using this as a variable in my script.
Example of what I have tried so far...
FOR /f "tokens=3 delims=5." %%a IN ('TYPE appsettings.config ^| FIND "ReleaseVersion"') DO SET do set word3=%%a
FOR /F delims^=^"^ tokens^=2 %%G IN ('FINDSTR /L "ReleaseVersion" "appsettings.config"')
FOR /f "tokens=3 usebackq delims== " %%G in (`appsettings.config`) do #echo %~G
Have tried a number of techniques but as yet, nothing has been successful.
Can post more information as required however that essentially covers the issue.
Supposing the add key="ReleaseVersion" value="5.2.0.2" portion is in a single line and the related value parameter appears after the ReleaseVersion substring, the following could work for you:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem define constants:
set "SEARCH=ReleaseVersion"
set "KEYWORD=value"
rem get line of interest and assign it to `LINE`:
for /F "delims=" %%L in ('findstr /L "%SEARCH%" "app.config"') do (
set "LINE=%%L"
)
setlocal EnableDelayedExpansion
rem cut everything off up to the search string:
set "LINE=!LINE:*%SEARCH%=!"
rem cut everything off up to the keyword:
set "LINE=!LINE:*%KEYWORD%=!"
rem extract the version number:
for /F tokens^=1^ delims^=^"^=^/^<^>^ %%N in ("!LINE!") do (
set "VNUM=%%N"
)
rem transfer the version number over the `setlocal`/`endlocal` barrier:
endlocal & endlocal & set "VNUM=%VNUM%"
echo ReleaseVersion: %VNUM%
exit /B
The string portion of interest does not need to look exactly like shown above, but may contain more or less spaces (for example add key = "ReleaseVersion" value = "5.2.0.2"), or include the " or not (like add key=ReleaseVersion value=5.2.0.2). The only condition is that the attribute key needs to appear before the attribute value.
If the search line is precisely this one:
add key="ReleaseVersion" value="5.2.0.2"
... then this code should work:
#echo off
setlocal
for /F "tokens=3" %%a in ('findstr "ReleaseVersion" "appsettings.config"') do set %%a
set "value=%value:~1,-1%"
echo %value%
If the layout of the search line change (more blank spaces or other characters, less quotes, etc) then previous code should need an adjustment.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q34445384.txt"
FOR /f "tokens=3delims==" %%a IN (
'findstr /L /c:"add key=\"ReleaseVersion\" value=" "%filename1%"') DO SET "release=%%~a"
ECHO release=%release%
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used a file named q34445384.txt containing your data for my testing.
Simply find the target string using findstr and set the environment variable to the third token using delimiters of =, removing the quotes from the value with ~.
This assumes uniqueness of the target text and that the structure of the line is exactly as posted.
Assuming app.config is valid, well-formed XML, the best way to scrape the release version is to query it via XPath. You can invoke PowerShell for this.
#echo off
setlocal
set "psCommand=powershell "^
select-xml \"//add[#key^='ReleaseVersion']\" app.config ^| %%{ $_.node.value };^
""
for /f %%I in ('%psCommand%') do set "version=%%~I"
echo %version%
This will parse app.config for a node named "add" which has an attribute named "key" whose value is "ReleaseVersion", then will return that node's "value" attribute's value. for /f captures it to a batch variable.
set NLM=^
set NL=^^^%NLM%%NLM%^%NLM%%NLM%
SET memoli=%token:QMZ=%NL%%%
echo %memoli%>>%tmp%\list2.txt
I cant change the string "QMZ" with a new line. How to do that?
Very simple
setlocal EnableDelayedExpansion
set "token=HelloQMZworld"
echo !token:QMZ=^
!
It works as the batch parser parses first the multiline caret and replace it with a single linefeed.
Then in the delayed expansion phase it replaces the QMZ with a single linefeed, which is legal in that phase.
To set a new variable with the replaced string simply use
setlocal EnableDelayedExpansion
set "token=HelloQMZworld"
set newVal=!token:QMZ=^
!
echo !newVal!
set LF=^
rem ** Two empty lines required
FOR /F "delims=" %%a in ("%token:QMZ=!LF!%") do (
echo %%a>>%tmp%\list2.txt
)
I was just wandering in the codes and I just did this unconsciously. But it does the trick.
I am reading, in a file, the first column which contains 0002C1, 0002C2, 0003C1, 0004C1
Extracting only the first 4 digits and put them in a variable.
FOR /F "tokens=1" %i IN (export.txt) DO (
echo %i
set s=%i:~0,4%
echo %s%
)
in output, the result of echo %i is correct, extracting the digits seems to be working fine also (when I try it for one entry, the result is correct) but the value of s seems to not change!
Can somebody see what the problem is?
Here is the output that I receive:
0002C1
%s%
0002C2
%s%
0003C1
%s%
0004C1
%s%
First: You need yo expand the variable using the SETLOCAL ENABLEDELAYEDEXPANSION command...
Second: you are trying to "cut" a special var (%i:~0,1%), you can't.
My solution:
#Echo OFF
:: By Elektro H#cker
FOR /F %%# IN (export.txt) DO (
Call Set "Token=%%#"
Call Set "Token=%%Token:~0,4%%"
Call Echo %%Token%%
)
Pause&Exit
There are a few issues with your script, only a few adjustments needed and it works great.
You need to use delayed expansion to access a variable that you create in a for loop.
setlocal enabledelayedexpansion
FOR /F "tokens=1" %%i IN (export.txt) DO (
echo %%i
set x=%%i
set s=!x:~0,4!
echo !s!
)
The only difference being you replace the %'s with !'s to tell cmd to use delayed expansion instead to read the variables.
When you are using a batch file you need to use double %'s for the for variables.
You also need to assign %%i to something so you can use a variable sign either side of it, in this case I have used x.