How to extract the numbers after a character in windows batch files - windows

Hi I do need to extract the last part of a string after the last dot
Example:
1.2.37 ==> I need the 37
1.2.567 ==> I need the 567
as you can see the number of characters after the dot is not fixed so expressions like
base=%fullver:~0,-2%
Can't be used. How can I achieve this?

#echo off
setlocal enableextensions disabledelayedexpansion
set "fullver=1.2.456"
for %%a in ("%fullver:.=\%") do set "base=%%~na"
echo %base%
The trick is to replace the dots with backslashes, process the string as a path and retrieve the name of the last element in it.
Alternatively, if all the elements need to be retrieved, instead of a for, a for /f is used to tokenize the variable using the dots as separators
#echo off
setlocal enableextensions disabledelayedexpansion
set "fullver=1.2.456"
for /f "tokens=1-3 delims=." %%a in ("%fullver%") do (
set "major=%%a"
set "minor=%%b"
set "build=%%c"
)
echo [%major%] [%minor%] [%build%]

I found the following question which actually tokenizes the string.
How to split a string in a Windows batch file?
May be you can try using this to delimit it with "." and take the last value stored in the string variable. Not sure if there is a simple way, but this works.
Here is an edited Version to fit your Needs:
#echo off
setlocal ENABLEDELAYEDEXPANSION
REM Set a string with an arbitrary number of substrings separated by semi colons
set teststring=1.2.5.234
for /f "tokens=1 delims=." %%a IN ("!teststring!") DO set firststring=%%a
echo !firststring!
REM Do something with each substring
:stringLOOP
REM Stop when the string is empty
if "!teststring!" EQU "" goto END
for /f "delims=." %%a in ("!teststring!") do set substring=%%a
REM Now strip off the leading substring
:striploop
set stripchar=!teststring:~0,1!
set teststring=!teststring:~1!
if "!teststring!" EQU "" goto stringloop
if "!stripchar!" NEQ "." goto striploop
goto stringloop
:END
echo !substring!
endlocal

I prefer MC ND's answer if you are looking for only the last node, or if you know how many nodes there are.
Here is a method to capture all nodes if the total number of nodes is unknown:
#echo off
setlocal enableDelayedExpansion
set "fullver=1.2.456"
:: Parse each node and store in an "array"
set cnt=0
for %%A in (%fullver:.= %) do (
set /a cnt+=1
set "node.!cnt!=%%A"
)
:: Show the results
for /l %%N in (1 1 %cnt%) do echo node.%%N = !node.%%N!

Another solution! This one gets the first and last parts of the string:
#echo off
setlocal
set "testString=1.2.5.234"
set "first="
for %%a in ("%testString:.=" "%") do (
if not defined first set "first=%%~a"
set "last=%%~a"
)
echo First: %first%
echo Last: %last%
As a bonus, this method correctly process special Batch characters that may appear in the string, excepting wild-cards.

You can use the below command to achieve what you want.
base=%fullver:~~4,3%
4 implies 4th digit i.e., 5 and 3 implies 3 digits from 4.
The output will be
567

Related

Batch for loop find string in variable

I want to find the string A in the variable Code=AAABASDG
and count each time 1 up if "A" was found so the result should be that it outputs 4 because in Code variable there are 4 A's
Example Code :
#echo off
set /A C=0
set Code=AAABASDG
for %%i in (%Code%) do IF "%%i"=="A" set /A C=%C%+1
echo %C%
pause
You could get the length of original string A, then delete the "A" letters from the string and get the length of the result, to finally subtract both lengths.
To easily get the length of the string, you could store it in a file and then ask for the %%~Z size of the file. Here it is:
#echo off
setlocal
set "Code=AAABASDG"
> before.txt echo %code%
> after.txt echo %code:A=%
for %%b in (before.txt) do for %%a in (after.txt) do set /A "count=%%~Zb-%%~Za"
echo %count%
The only drawback of this method is that it is not case-aware: both upcase and lowcase letters are delete in the replacement operation
#echo off
set /A C=0
set "Code=AAABASDG"
:loop
if defined code (
if "%code:~-1%"=="A" set /a C+=1
set "code=%code:~0,-1%"
goto loop
)
echo %C%
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign " or a terminal backslash or Space. Build pathnames from the elements - counterintuitively, it is likely to make the process easier.
Substrings in batch are obtained from %var:~m,n% where ,n is optional; m is count-of-chars-from-beginning-of-string, from end if negative. ,n positive = max length to return; negative = end-position in chars from end; missing=return all after m
Here's a quick example which gets help from PowerShell:
#Echo Off
SetLocal EnableExtensions
Set "Code=AAABASDG"
For /F %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe
-NoProfile "[RegEx]::Matches('%Code%','A').Count"') Do Set "C=%%G"
Echo(%C%
Pause

Last token in batch delimited by minus

I have a string "xx-yy-zz"
I need to get the part after the last minus character.
Usually, I do it that way
FOR /F "tokens=1-3 delims=-" %%i IN ("xx-yy-zz") DO SET USER_COUNTRY=%%k
echo Country: %USER_COUNTRY%
But now I don't have the string with a fixed length (there could be 2/3/4 delimiters)
How can I specify that I want the last one? So I have the code that would work for "xx-yy-zz" and also for "xx-yy-zz-aa"
Could someone help with this, please?
use a plain for (without /f):
set string=xxx-yyy-zzz
for %%a in (%string:-= %) do set last=%%a
echo %last%
(%string:-= % replaces every - with a space, so the for can split the string into tokens and assign every one of them to (the same) variable, resulting in the variable holding the last token.
The option string tokens=1-4 would let the for /F loop assign the last string portion aa to variable reference %%l if it is present; %%l would be empty otherwise. So you could do an if query to check for emptyness and use %%k instead in case, and so on, like this:
for /F "tokens=1-4 delims=-" %%i in ("xx-yy-zz-aa") do (
set "USER_COUNTRY=%%l"
if not defined USER_COUNTRY set "USER_COUNTRY=%%k"
if not defined USER_COUNTRY set "USER_COUNTRY=%%j"
)
echo/%USER_COUNTRY%
An alternative method would be this:
set "STRING=xx-yy-zz-aa"
set "DUMMY=%STRING:-=" & set "USER_COUNTRY=%"
echo/%USER_COUNTRY%
This approach might fail if the input string contains " characters.
One solution could be to convert the string, replacing dashes with backslashes so it "seems" a path that can be handled with a for command
#echo off
setlocal enableextensions disabledelayedexpansion
set "string=xxx-yyy-zzz"
for /f "delims=" %%a in ("::%string:-=\%") do set "last=%%~nxa"
echo %last%
An additional example:
#Echo Off
Set/P "InString=Enter your delimited string: "
Echo=
If "%InString%"=="" GoTo :EOF
Set/P "Delimiter=Enter the delimiter: "
Echo=
If "%Delimiter%"=="" GoTo :EOF
Set "Delimiter=%Delimiter:~,1%"
:Loop
If Defined InString (
For /F "EOL=%Delimiter% Tokens=1* Delims=%Delimiter%" %%A In ("%InString%"
) Do (Set "LastToken=%%A" & Set "InString=%%B") & GoTo Loop
) Else Set LastToken
Timeout -1
Exit/B
This version will still have issues with some characters

Joining a list of numbers in a .txt file with ,[space]

Hi I managed to get the code below to create a list of numbers and place a comma at the end of each number created However, it has proven to be quite the challenge to get them on the same line separated by a ,[space]
#ECHO OFF
setlocal EnableDelayedExpansion
set _Output=%UserProfile%\Desktop\NumGen.txt
::only change these three lines
set "start=1" ::starts from this number
set "amount=10" ::amount of files created
set "length=5" ::length of fileNames
set "join_with=, " ::what to join each number with
set /a "last=%start%+%amount%"
for /l %%i in (%start%,1,%last%) do (
set "folderName=0000000000%%i"
set "folderName=!folderName:~-%length%!%join_with%"
>>"%_Output%" ECHO.!folderName!
)
pause
so my output at the moment is
00001,
00002,
00003,
00004,
00005,
00006,
00007,
00008,
00009,
00010,
00011,
However I would like it to be
00001, 00002, 00003, 00004, 00005, 00006, 00007, 00008, 00009, 00010, 00011
I have windows 10 64bit. Any help will be appreciated
echo is not able to do that. But there is a workaround, (ab)using the set command:
for /l %%i in (1,1,5) do (
<nul set /p "=%%i, "
)
echo(
After a long break I decided to give this another bash and presto. Success :-)
::CallScript
#ECHO OFF
CALL :ScriptA
CALL :ScriptB
CALL :ScriptC
pause
goto :eof
:ScriptA
#ECHO OFF
setlocal EnableDelayedExpansion
set _Output=%UserProfile%\Desktop\NumGen.txt
::only change these three lines
set "start=1"
set "amount=10"
set "length=5"
set "join_with=, "
set /a "last=%start%+%amount%"
for /l %%i in (%start%,1,%last%) do (
set "folderName=0000000000%%i"
set "folderName=!folderName:~-%length%!%join_with%"
>>"%_Output%" ECHO.!folderName!
)
goto :eof
:ScriptB
#ECHO OFF
setlocal enableextensions enabledelayedexpansion
set "var="
for /f "usebackq delims=" %%a in ("%UserProfile%\Desktop\NumGen.txt") do set "var=!var!%%a"
echo %var%> "%UserProfile%\Desktop\NumList.txt"
goto :eof
:ScriptC
#ECHO OFF
del "%UserProfile%\Desktop\NumGen.txt"
goto :eof
This code determines the starting number, the amount of numbers, the length of the numbers and joins them with , "
Then ScriptB concatenates each number together with the , " and saves to NumList.txt
Lastly the script deletes the NumGen.txt file.
Stephan has one solution with SET /P. The other option is to build the entire string within an environment variable, and then write after the loop ends. This is significantly faster, but it will fail if the final string length exceeds ~8191 bytes.
set "str="
for /l %%i in (%start%,1,%last%) do (
set "folderName=0000000000%%i"
set "str=!str!!folderName:~-%length%!%join_with%"
)
>>"%_Output%" ECHO.!str!
You could remove the unwanted trailing , if you want:
>>"%_Output%" ECHO.!str:~0,-2!

How to find total commas in the first line of a file?

I want create a batch file to find the total number of commas in the first line of text file.
Sample Text File
input.txt
12345,Bhavik
12323,Bhavik,Sanghvi
Output
1
I tried to surf net for this but couldnt find a solution, please help
Here's another simple solution to this question.
#echo off
setlocal enabledelayedexpansion
set LF=^
::Above 2 blank lines are critical - do not remove
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set /p var=<input.txt
echo "%var:,="!cr!!lf!"..***..%">temp.file
find /c "..***.." <temp.file
del temp.file
#echo off
setlocal EnableDelayedExpansion
rem Read the first line
set /P "line=" < input.txt
rem Store it in a text file
> before.txt echo !line!
rem Store the line without commas in a second file
> after.txt echo !line:,=!
rem Get the difference in sizes between both files
set "diff="
for %%a in (before.txt after.txt) do (
if not defined diff (
set "diff=%%~Za"
) else (
set /A "diff-=%%~Za"
)
)
del before.txt after.txt
echo %diff%
If, rather than being hampered by the awful Windows BATCH tools, you install awk from the Unix tools for Windows here, you can do this:
awk -F, 'NR==1{print NF-1;exit}' input.txt
That says... "Run awk and use commas as the separator to divide fields. On line 1, print the number of fields on this line minus 1, then exit. Do that for file input.txt."
gawk is just a slightly different version of awk if you get that one in the Unix Utils package. You may need to replace the single quotes with double ones to accommodate Windows' lack of abilities.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q35826440.txt"
:: first method
SET /a count=0
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO SET "line=%%a"&GOTO got1
:got1
SET "line=%line:"=%"
IF NOT DEFINED line ECHO method 1: %count% found&GOTO method2
IF "%line:~-1%"=="," SET /a count+=1
SET "line=%line:~0,-1%"
GOTO got1
:: second method
:method2
SET /a count=-1
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO SET "line=%%a"&GOTO got2
:got2
SET "line=%line:"=%"
SET "line=%line:;=%"
SET "line=%line: =%"
SET "line=%line:,=x,x%"
FOR %%a IN (%line%) DO SET /a count+=1
ECHO method 2: %count% found
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used a file named q35826440.txt containing your data for my testing.
Two methods - both read the first line to line, then removes any " characters.
The first then mechanically loops, checking whether the last character is a comma, counting if it is and removing the last character until the string found is empty.
The second replaces all ; and Space characters (for good measure, Tab could be removed too) and then replacing commas with x,x.
The result is that the only separators left are commas, and there will be 1 more item in the list so formed than there are commas.
Hence, start the counter at -1 and increment for each element found in the list.
Next solution (similar to Magoo's second method) seems to treat even ˙cmd˙ and .bat poisonous characters supposed in input file:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "infile=D:\bat\SO\files\35826440input.txt" change to suit your circumstances
set /A "commacount=-1"
for /F "usebackq delims=" %%G in ("%infile%") do (
set "line=%%G"
call :parseline
if /I not "%~1"=="/all" goto :continue
)
:continue
echo script continues here
ENDLOCAL
exit /B
:parseline
rem treat unbalanced doublequote in next line
set "lineToParse=%line:"=§%"
set "lineToParse=%lineToParse:,=","%"
set /A "commacount=-1"
for %%g in ("%lineToParse%") do (
set /A "commacount+=1"
rem echo %line%, !commacount!, %%g
)
echo %commacount% "%line%"
goto :eof
Output (with input file listing):
==> D:\bat\SO\35826440.bat
1 "12345,Bhavik"
script continues here
==> D:\bat\SO\35826440.bat /all
1 "12345,Bhavik"
2 "12323,Bhavik,Sanghvi"
3 "12323,Bhavik,Sanghvi,three"
0 "zero"
1 ",1 leading"
2 ",,2 leading"
1 "trailing,"
2 "2 trailing,,"
2 "2 middle,,mid"
4 "!OS!,!,!!,!!!,exclamations"
4 "%OS%,%,%%%,%%,percents"
8 "&,|,>,<,",",;,=,miscelaneous"
0 "unbalanced"doublequote"
script continues here
==> type D:\bat\SO\files\35826440input.txt
12345,Bhavik
12323,Bhavik,Sanghvi
12323,Bhavik,Sanghvi,three
zero
,1 leading
,,2 leading
trailing,
2 trailing,,
2 middle,,mid
!OS!,!,!!,!!!,exclamations
%OS%,%,%%%,%%,percents
&,|,>,<,",",;,=,miscelaneous
unbalanced"doublequote
==>

Batch Scripting:search file, extract numbers, and copy into new file

I'm new to batch scripting and have a question. I was wondering if it's possible to search a .txt file by requirements and take data specified and copy into a new .txt file?
Like if I have 50 lines with 9 digit numbers and a bunch of other crap I don't need after them can I say,
"For any line beginning with a 1,2,3,4,5,6,7,8,or 9...take the first 9 digits and copy them into a new file, for all lines in the file???"
I thought this would be easier than trying to delete all the other stuff. Let me know if you know anything about how to do this! Thanks.
Here's an example of what one line looks like:
123456789#example
and I just need to extract the 9 digit numbers from about 50 lines of this.
You can use FINDSTR to filter out all lines that do not start with 9 digits. Then FOR /F can read the result, line by line. A variable is set, and a substring operation preserves just the first 9 digits.
#echo off
setlocal enableDelayedExpansion
(
for /f %%A in (
'findstr "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" yourFile.txt'
) do (
set "ln=%%A"
echo !ln:~0,9!
)
)>newFile.txt
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /f "delims=" %%a IN (q24824079.txt) DO (
SET "line=%%a"
REM set DIGITS to the first 9 characters of LINE
SET "digits=9!line:~0,9!"
FOR /L %%z IN (0,1,9) DO SET "digits=!digits:%%z=!"
IF NOT DEFINED digits ECHO(!line:~0,9!
)
)>newfile.txt
GOTO :EOF
I used a file named q24824079.txt containing data for my testing.
Produces newfile.txt
You did not specfy what to do if the line was all-digits but has fewer than 9 characters. I chose to report that line.
Hopefully this helps getting the job done:
#echo off
setlocal enabledelayedexpansion
for /f %%e in (emails.txt) do (
echo Email: %%e
for /f "delims=# tokens=1" %%b in ("%%e") do (
set BEGIN=%%b
echo Name: !BEGIN!
set FIRST=!BEGIN:~0,1!
echo First char: !FIRST!
set /a NUMERIC=!FIRST!+0
echo Converted to number: !NUMERIC!
if !FIRST!==!NUMERIC! echo Yippieh!
echo.
)
)
Instead of echo Yippieh! append the email (%%e) to a file, e.g. like
echo %%e >> output.txt

Resources