I don't understand why this doesn't work
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set contents=sdflkm efsdf sdfkns CRQ239478239
for /f "tokens=1* delims= " %%i in ("%contents%") do (
set str=%%i
echo str: !str:~0,3!
if "!str:~0,3!"=="CRQ" (
set revision=!str!
)
)
echo revision: %revision%
I want to extract the word in the string that begins with "CRQ". But this for loop only does one iteration, grabbing the first 3 letters of the string. The output is just str: sdf
. It should check the first 3 letters of every word in the string, and if the first 3 letters are 'CRQ', it should set the revision variable to the word containing CRQ. How do I do this?
The for
command will iterate through lines of input. Since your string only consists of a single line you only get 1 iteration through your loop.
The for
loop is tokenizing that single line into multiple tokens. It is passing the first token to %i
, then, thanks to the asterisk in tokens=1*
, it puts the rest in %j
. If you change your script a little, you can see this:
set contents=sdflkm efsdf sdfkns CRQ239478239
for /f "tokens=1*" %%i in ("%contents%") do (
set str=%%i
echo str: !str:~0,3!
echo rest: %%j
if "!str:~0,3!"=="CRQ" (
set revision=!str!
)
)
echo revision: %revision%
which outputs:
str: sdf
rest: efsdf sdfkns CRQ239478239
revisionx:
My solution is to create a subroutine that you can call recursively on the remaining tokens until you hit the one you want:
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set contents=sdflkm efsdf sdfkns CRQ239478239
call :ParseTokens %contents%
echo revision: %revision%
rem Subroutine ParseTokens
:ParseTokens
set ToParse=%*
for /f "tokens=1*" %%i in ("%ToParse%") do (
set str=%%i
if "!str:~0,3!"=="CRQ" (
set revision=!str!
exit /b
) else (
call :ParseTokens %%j
)
)
exit /b
Just change your For /F
loop to a standard For
loop:
@Echo Off
SetLocal EnableDelayedExpansion
Set "Contents=sdflkm efsdf sdfkns CRQ239478239"
Set "Revision="
For %%A In (%Contents%) Do (Set "Str=%%A"
Echo Str: !Str:~,3!
If /I "!Str:~,3!"=="CRQ" Set "Revision=!Str!")
Set "Str="
If Defined Revision Echo %Revision%
Pause
Change your for to a simple one and use %contents%
without quotes.
for %%i in (%contents%) do (
Just another variant with a call and shifting arguments:
@echo off & SETLOCAL
set contents=sdflkm efsdf sdfkns CRQ239478239
Call :Sub %contents%
echo revision: %revision%
goto :eof
:sub
set str=%1
echo str: %str:~0,3%
if "%str:~0,3%"=="CRQ" set revision=%str%
If "%~2" neq "" (shift & goto :sub)
Just adding another method to achieve this, using a file as input called My CRQs.txt
The idea here is to break up each string into words so findstr
will only return what you asked off it.:
@echo off
for /f "usebackq delims=" %%i in ("My CRQs.txt") do (
for %%a in (%%i) do echo %%a | findstr /IBRC:"CRQ"
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.