Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
Rileyh
- Posts: 147
- Joined: 01 Sep 2011 03:54
- Location: Perth, Western Australia
#1
Post
by Rileyh » 08 Dec 2011 01:48
Hi guys,
I have a "for /f" string:
Code: Select all
@echo off
setlocal enabledelayedexpansion
set "$match=(values here vary)"
set "$file=test.txt"
for /f "tokens=1-2*" %%a in ('findstr /b /i "!$match!" "!$file!"') do (
) set "b=%%a"
set "rest=!b:*$match=!"
(do something here)
)
When I run this code (can I note that it is run as a block in a batch file that has this same code over and over) it finds all occurrences, not just the one. I need it to find it only once and then move on wit the batch file.
Can you show me how to do this?
Regards,
Rileyh
-
Ed Dyreen
- Expert
- Posts: 1569
- Joined: 16 May 2011 08:21
- Location: Flanders(Belgium)
-
Contact:
#2
Post
by Ed Dyreen » 08 Dec 2011 02:14
'
Code: Select all
@echo off &setlocal enabledelayedexpansion
set "$match=(values here vary)"
set "$file=test.txt"
set "b=" &for /f "tokens=1-2*" %%a in (
'findstr /bi "!$match!" "!$file!"'
) do if not defined b (
set "b=%%a"
set "rest=!b:*$match=!"
REM *****(do something here)*****
)
-
dbenham
- Expert
- Posts: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#3
Post
by dbenham » 08 Dec 2011 07:34
better yet:
Code: Select all
@echo off
setlocal enabledelayedexpansion
set "$match=(values here vary)"
set "$file=test.txt"
findstr /b /i "!$match!" "!$file!" >nul && do something if match is found
Be careful - FINDSTR without using /C option defaults to interpreting the search string as a regular expression
Use the /L option to treat it as a literal.
Dave Benham
-
orange_batch
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
-
Contact:
#4
Post
by orange_batch » 09 Dec 2011 03:20
Here's a solution that should be better than Ed's, since it doesn't keep iterating doing nothing but if defined comparisons, this is how you typically break out of a for loop in batch.
Pseudo-code:
Code: Select all
for ... ... (
code ...
goto break
)
:break
Can be used any number of times in your scripts, as goto will always go to the first label found after where it's executed. Of course, you can't go to a specific break though if you have multiple copies.
-
dbenham
- Expert
- Posts: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#5
Post
by dbenham » 09 Dec 2011 07:13
orange_batch wrote:Can be used any number of times in your scripts, as goto will always go to the first label found after where it's executed. Of course, you can't go to a specific break though if you have multiple copies.
Actually you can re-use the same label like this BECAUSE it always goes to the first matching label found from current position.
Code: Select all
for ... do (
...
goto :break
)
:break
for ... do (
...
goto :break
)
:break
The above will actually work as desired every time. But this is highly discouraged as it is confusing.
orange_batch wrote:since it doesn't keep iterating doing nothing
The goto :break is much faster because the DO clause is skipped after the first execution of the GOTO. But the iterations are completed. This script will never end
Code: Select all
@echo off
for /l %%a in (1 0 1) do goto :break
:break
Dave Benham
-
jeb
- Expert
- Posts: 1055
- Joined: 30 Aug 2007 08:05
- Location: Germany, Bochum
#6
Post
by jeb » 09 Dec 2011 17:00
dbenham wrote:The goto :break is much faster because the DO clause is skipped after the first execution of the GOTO. But the iterations are completed. This script will never end
The iterations are only fully "completed" with FOR /L, FOR /F can be break instantly.
FOR /R can't be brake, but the ECHO ON-output will be suppressed.
Code: Select all
@echo on
cls
for /F %%a in (1 2 3) do (
echo %%a
goto :break
)
:break
for /L %%a in (1 1 3) do (
echo %%a
goto :break
)
:break
for /R %%a in (1 2 3) do (
echo %%a
goto :break
)
:break
exit /b
jeb
-
orange_batch
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
-
Contact:
#7
Post
by orange_batch » 09 Dec 2011 18:48
dbenham wrote:orange_batch wrote:Can be used any number of times in your scripts, as goto will always go to the first label found after where it's executed. Of course, you can't go to a specific break though if you have multiple copies.
Actually you can re-use the same label like this BECAUSE it always goes to the first matching label found from current position.
Code: Select all
for ... do (
...
goto :break
)
:break
for ... do (
...
goto :break
)
:break
The above will actually work as desired every time. But this is highly discouraged as it is confusing.
orange_batch wrote:since it doesn't keep iterating doing nothing
The goto :break is much faster because the DO clause is skipped after the first execution of the GOTO. But the iterations are completed. This script will never end
Code: Select all
@echo off
for /l %%a in (1 0 1) do goto :break
:break
Dave Benham
Actually all of that is entirely what I meant by what I wrote, lol.
I'm saying you can use break any number of times, but you can't go to a
specific one other than the first one found of course.