"For /f" string needs to run only once

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Rileyh
Posts: 147
Joined: 01 Sep 2011 03:54
Location: Perth, Western Australia

"For /f" string needs to run only once

#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:

Re: "For /f" string needs to run only once

#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)

Re: "For /f" string needs to run only once

#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:

Re: "For /f" string needs to run only once

#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)

Re: "For /f" string needs to run only once

#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. :wink:

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: 1041
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: "For /f" string needs to run only once

#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:

Re: "For /f" string needs to run only once

#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. :wink:

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. 8) 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.

Post Reply