• Welcome to Tux Reports: Where Penguins Fly. We hope you find the topics varied, interesting, and worthy of your time. Please become a member and join in the discussions.

Problem with DOS batch file - FOR loop

S

Scott Bass

Flightless Bird
Hi,

I'm not sure this is the correct newsgroup - if not, can you please suggest
the appropriate one for a DOS batch question? Thanks...

I'd love to code my problem in VBS, PowerShell, Perl, Python, Ruby, ...
anything but DOS. Since I can't, here's my problem: (Note: I can't
install ANY additional s/w on the end user's machines and can't use VBS)

I've got a config file for an application that looks like:

-log "C:/Some\Path To\My Config\File\config.cfg"

I have to parse this file, extracting the value for the logs location into a
variable, in order to search the generated logs after the application
executes. The problem comes from the spaces in the file path.

I've got this code (with lots of debugging stub statements):

setlocal

FOR /F "usebackq tokens=2-5* delims= " %%a IN (`findstr /i /c:-log
"%config%"`) DO (
echo A %%a
echo B %%b
echo C %%c
echo D %%d
echo E %%e

if defined A echo A IS DEFINED
if defined B echo B IS DEFINED
if defined C echo C IS DEFINED
if defined D echo D IS DEFINED
if defined E echo E IS DEFINED

if not dummy==dummy%%a echo A IS NOT BLANK
if not dummy==dummy%%b echo B IS NOT BLANK
if not dummy==dummy%%c echo C IS NOT BLANK
if not dummy==dummy%%d echo D IS NOT BLANK
if not dummy==dummy%%e echo E IS NOT BLANK

if not dummy==dummy%%a set logs=%%a
if not dummy==dummy%%b set logs=%%logs %%b
if not dummy==dummy%%c set logs=%%logs %%c
if not dummy==dummy%%d set logs=%%logs %%d
if not dummy==dummy%%e set logs=%%logs %%e

echo %%logs
)

echo %%logs

It's not ideal, since I could (in theory) have a path with more than 5 space
separated tokens. But not likely, so I can live with this. I have a
feeling the problem could be due to immediate vs. delayed variable
resolution. And I may be using %%var vs. %var% incorrectly.

Ideally, I'd like to retrieve the line from the log, and do a search and
replace on "-log" (s/-log//g in say Perl or vi on Unix). But I can't see
how to do this in a DOS batch file. If there is a way to do a search and
replace in DOS OOTB, that would be great.

Any ideas how to parse the above to return the results equivalent to:

set logs="C:/Some\Path To\My Config\File\config.cfg"

Thanks,
Scott
 
P

Pegasus [MVP]

Flightless Bird
"Scott Bass" <sas_l_739@SPAMMERSAREEVIL.yahoo.com.au.REMOVETHIS> wrote in
message news:eiTDo19xKHA.2012@TK2MSFTNGP04.phx.gbl...
> Hi,
>
> I'm not sure this is the correct newsgroup - if not, can you please
> suggest
> the appropriate one for a DOS batch question? Thanks...
>
> I'd love to code my problem in VBS, PowerShell, Perl, Python, Ruby, ...
> anything but DOS. Since I can't, here's my problem: (Note: I can't
> install ANY additional s/w on the end user's machines and can't use VBS)
>
> I've got a config file for an application that looks like:
>
> -log "C:/Some\Path To\My Config\File\config.cfg"
>
> I have to parse this file, extracting the value for the logs location into
> a
> variable, in order to search the generated logs after the application
> executes. The problem comes from the spaces in the file path.
>
> I've got this code (with lots of debugging stub statements):
>
> setlocal
>
> FOR /F "usebackq tokens=2-5* delims= " %%a IN (`findstr /i /c:-log
> "%config%"`) DO (
> echo A %%a
> echo B %%b
> echo C %%c
> echo D %%d
> echo E %%e
>
> if defined A echo A IS DEFINED
> if defined B echo B IS DEFINED
> if defined C echo C IS DEFINED
> if defined D echo D IS DEFINED
> if defined E echo E IS DEFINED
>
> if not dummy==dummy%%a echo A IS NOT BLANK
> if not dummy==dummy%%b echo B IS NOT BLANK
> if not dummy==dummy%%c echo C IS NOT BLANK
> if not dummy==dummy%%d echo D IS NOT BLANK
> if not dummy==dummy%%e echo E IS NOT BLANK
>
> if not dummy==dummy%%a set logs=%%a
> if not dummy==dummy%%b set logs=%%logs %%b
> if not dummy==dummy%%c set logs=%%logs %%c
> if not dummy==dummy%%d set logs=%%logs %%d
> if not dummy==dummy%%e set logs=%%logs %%e
>
> echo %%logs
> )
>
> echo %%logs
>
> It's not ideal, since I could (in theory) have a path with more than 5
> space
> separated tokens. But not likely, so I can live with this. I have a
> feeling the problem could be due to immediate vs. delayed variable
> resolution. And I may be using %%var vs. %var% incorrectly.
>
> Ideally, I'd like to retrieve the line from the log, and do a search and
> replace on "-log" (s/-log//g in say Perl or vi on Unix). But I can't see
> how to do this in a DOS batch file. If there is a way to do a search and
> replace in DOS OOTB, that would be great.
>
> Any ideas how to parse the above to return the results equivalent to:
>
> set logs="C:/Some\Path To\My Config\File\config.cfg"
>
> Thanks,
> Scott


It might be appropriate to start by cleaning out some misunderstandings.
There is no such thing as a "DOS batch file". DOS is an operating system
that was introduced more than 30 years ago. It is only rarely used these
days and it does not exist under Windows XP. Under Windows XP you have the
Console (or Command Prompt), much like the console under non-Microsoft OSs.
Although it's black and character based, it has very little in common with
DOS.

About your batch file - how about something like the code below. Note that
most of its instructions would fail under DOS. And by the way - if you don't
like coding batch files, what prevents you from writing a small VB Script
file? Cscript.exe is native to all current flavours of Windows and the code
would be quite trivial.

@echo off
set Line=x
for /F "delims=" %%a in ('type "d:/temp\test.txt" ^| find /i "-log "') do
set Line=%%a
if x==%Line% goto :eof
set Line=%Line:-log=%
for /F "delims=" %%a in ('echo %Line%') do set LogPath=%%a
echo LogPath=%LogPath%
 
D

Don Wiss

Flightless Bird
On Sat, 20 Mar 2010, "Pegasus [MVP]" <news@microsoft.com> wrote:

>It might be appropriate to start by cleaning out some misunderstandings.
>There is no such thing as a "DOS batch file". DOS is an operating system
>that was introduced more than 30 years ago. It is only rarely used these
>days and it does not exist under Windows XP. Under Windows XP you have the
>Console (or Command Prompt), much like the console under non-Microsoft OSs.
>Although it's black and character based, it has very little in common with
>DOS.


I knew you were going to jump in and say that. You *NEVER* miss an
opportunity to point out to people using the word DOS that DOS no longer
exists.

Don <www.donwiss.com> (e-mail link at home page bottom).
 
P

Pegasus [MVP]

Flightless Bird
"Don Wiss" <donwiss@no_spam.com> wrote in message
news:il6aq5hrt9hkme5ndpvk98mc4c9sb7td6s@4ax.com...
> On Sat, 20 Mar 2010, "Pegasus [MVP]" <news@microsoft.com> wrote:
>
>>It might be appropriate to start by cleaning out some misunderstandings.
>>There is no such thing as a "DOS batch file". DOS is an operating system
>>that was introduced more than 30 years ago. It is only rarely used these
>>days and it does not exist under Windows XP. Under Windows XP you have the
>>Console (or Command Prompt), much like the console under non-Microsoft
>>OSs.
>>Although it's black and character based, it has very little in common with
>>DOS.

>
> I knew you were going to jump in and say that. You *NEVER* miss an
> opportunity to point out to people using the word DOS that DOS no longer
> exists.
>
> Don <www.donwiss.com> (e-mail link at home page bottom).


Yes, you're right, and by the same token I never miss an opportunity to
point out that the earth was not created 6781 years ago (or whatever that
number might be). Both claims are flawed and lead to erroneous conclusions.
At the same time I spent ten minutes to give the OP a workable solution to
his problem.
 
D

Don Wiss

Flightless Bird
On Sat, 20 Mar 2010, "Pegasus [MVP]" <news@microsoft.com> wrote:

>Don Wiss wrote:
>> I knew you were going to jump in and say that. You *NEVER* miss an
>> opportunity to point out to people using the word DOS that DOS no longer
>> exists.

>
>Yes, you're right, and by the same token I never miss an opportunity to
>point out that the earth was not created 6781 years ago (or whatever that
>number might be). Both claims are flawed and lead to erroneous conclusions.
>At the same time I spent ten minutes to give the OP a workable solution to
>his problem.


Except in this case we can assume that the OP knows that the original DOS
is now gone, and was just using DOS as slang for the command prompt. In
contrast, the people that believe the earth is only "6781" years old really
do believe it and nothing you say will convince them otherwise. And you
can't even argue with them. For example. You point out that objects can be
dated to much older. They will respond that god is so great he can make
things appear old. How do you respond to that?

Don <www.donwiss.com> (e-mail link at home page bottom).
 
P

Pegasus [MVP]

Flightless Bird
"Don Wiss" <donwiss@no_spam.com> wrote in message
news:f1aaq5t42ceba7f2ku0v2b563352tbduar@4ax.com...
> On Sat, 20 Mar 2010, "Pegasus [MVP]" <news@microsoft.com> wrote:
>
>>Don Wiss wrote:
>>> I knew you were going to jump in and say that. You *NEVER* miss an
>>> opportunity to point out to people using the word DOS that DOS no longer
>>> exists.

>>
>>Yes, you're right, and by the same token I never miss an opportunity to
>>point out that the earth was not created 6781 years ago (or whatever that
>>number might be). Both claims are flawed and lead to erroneous
>>conclusions.
>>At the same time I spent ten minutes to give the OP a workable solution to
>>his problem.

>
> Except in this case we can assume that the OP knows that the original DOS
> is now gone, and was just using DOS as slang for the command prompt. In
> contrast, the people that believe the earth is only "6781" years old
> really
> do believe it and nothing you say will convince them otherwise. And you
> can't even argue with them. For example. You point out that objects can be
> dated to much older. They will respond that god is so great he can make
> things appear old. How do you respond to that?
>
> Don <www.donwiss.com> (e-mail link at home page bottom).


I try to give the OP a solution that works.
 
S

Scott Bass

Flightless Bird
Hi, see comments inline below...

"Pegasus [MVP]" <news@microsoft.com> wrote in message
news:esxi0JCyKHA.5936@TK2MSFTNGP04.phx.gbl...
>
>
> "Scott Bass" <sas_l_739@SPAMMERSAREEVIL.yahoo.com.au.REMOVETHIS> wrote in
> message news:eiTDo19xKHA.2012@TK2MSFTNGP04.phx.gbl...
>> Hi,
>>
>> I'm not sure this is the correct newsgroup - if not, can you please
>> suggest
>> the appropriate one for a DOS batch question? Thanks...
>>
>> I'd love to code my problem in VBS, PowerShell, Perl, Python, Ruby, ...
>> anything but DOS. Since I can't, here's my problem: (Note: I can't
>> install ANY additional s/w on the end user's machines and can't use VBS)
>>
>> I've got a config file for an application that looks like:
>>
>> -log "C:/Some\Path To\My Config\File\config.cfg"
>>
>> I have to parse this file, extracting the value for the logs location
>> into a
>> variable, in order to search the generated logs after the application
>> executes. The problem comes from the spaces in the file path.
>>
>> I've got this code (with lots of debugging stub statements):
>>
>> setlocal
>>
>> FOR /F "usebackq tokens=2-5* delims= " %%a IN (`findstr /i /c:-log
>> "%config%"`) DO (
>> echo A %%a
>> echo B %%b
>> echo C %%c
>> echo D %%d
>> echo E %%e
>>
>> if defined A echo A IS DEFINED
>> if defined B echo B IS DEFINED
>> if defined C echo C IS DEFINED
>> if defined D echo D IS DEFINED
>> if defined E echo E IS DEFINED
>>
>> if not dummy==dummy%%a echo A IS NOT BLANK
>> if not dummy==dummy%%b echo B IS NOT BLANK
>> if not dummy==dummy%%c echo C IS NOT BLANK
>> if not dummy==dummy%%d echo D IS NOT BLANK
>> if not dummy==dummy%%e echo E IS NOT BLANK
>>
>> if not dummy==dummy%%a set logs=%%a
>> if not dummy==dummy%%b set logs=%%logs %%b
>> if not dummy==dummy%%c set logs=%%logs %%c
>> if not dummy==dummy%%d set logs=%%logs %%d
>> if not dummy==dummy%%e set logs=%%logs %%e
>>
>> echo %%logs
>> )
>>
>> echo %%logs
>>
>> It's not ideal, since I could (in theory) have a path with more than 5
>> space
>> separated tokens. But not likely, so I can live with this. I have a
>> feeling the problem could be due to immediate vs. delayed variable
>> resolution. And I may be using %%var vs. %var% incorrectly.
>>
>> Ideally, I'd like to retrieve the line from the log, and do a search and
>> replace on "-log" (s/-log//g in say Perl or vi on Unix). But I can't see
>> how to do this in a DOS batch file. If there is a way to do a search and
>> replace in DOS OOTB, that would be great.
>>
>> Any ideas how to parse the above to return the results equivalent to:
>>
>> set logs="C:/Some\Path To\My Config\File\config.cfg"
>>
>> Thanks,
>> Scott

>
> It might be appropriate to start by cleaning out some misunderstandings.
> There is no such thing as a "DOS batch file". DOS is an operating system
> that was introduced more than 30 years ago. It is only rarely used these
> days and it does not exist under Windows XP. Under Windows XP you have the
> Console (or Command Prompt), much like the console under non-Microsoft
> OSs. Although it's black and character based, it has very little in common
> with DOS.


Thanks for the clarification (I'm not being sarcastic). I do want to use
correct terminology.

Rhetorical questions not requiring a reply: Wasn't Windows 95 just slapped
on top of DOS? Does Windows XP still have a boot option to boot to DOS
mode? Don't some low level disk utilities require a Windows machine to boot
into DOS mode?

>
> About your batch file - how about something like the code below. Note that
> most of its instructions would fail under DOS. And by the way - if you
> don't like coding batch files, what prevents you from writing a small VB
> Script file? Cscript.exe is native to all current flavours of Windows and
> the code would be quite trivial.


Yeah, I'm re-thinking this. I'm no guru in VB Script, but have written a
few, and Google is my friend (plus other microsoft.public... newsgroups).
The issue is that no one else in my department knows VB Script, so the
script would be difficult to maintain or clone/modify. A minor issue is
that the default windows host engine (if that's the right term) can vary
between cscript and wscript across user's machines. I think (???) if I used
some wscript commands, such as displaying a message dialog, and the script
was running under cscript, that it would fail.

I wish there was a way for a script to force itself to run under a
particular engine...a bit like #!/bin/sh, #!/bin/ksh, or #!/bin/bash under
Unix, where the processing shell is determined by the specially formatted
comment in the first line.

> @echo off
> set Line=x
> for /F "delims=" %%a in ('type "d:/temp\test.txt" ^| find /i "-log "') do
> set Line=%%a
> if x==%Line% goto :eof
> set Line=%Line:-log=%
> for /F "delims=" %%a in ('echo %Line%') do set LogPath=%%a
> echo LogPath=%LogPath%


Thanks for this, much appreciated.

Finally, I did read with some amusement the rest of the messages in this
thread. Man, I'm so flat out with work, I'd never have time to get into
such dialogue! Why not just add him into your kill file, or just ignore his
messages? Someone gets oh, one chance at being negative with me before
they're blocked and I never hear from them again :)

Again, thanks for the help.

Cheers,
Scott
 
S

Scott Bass

Flightless Bird
I'm still having problems getting this to work. Here is my test
script:

set config=C:/Temp\config.cfg

set Line=###
for /F "delims=" %%A in ('type "%config%" ^| find /i "-log "') do set
Line=%%A
echo %Line%

if ###==%Line% (
echo ERROR: Unable to determine logs directory from config file.
goto debug
)

set Line=%Line:-log=%
for /F "delims=" %%A in ('echo %Line%') do set LogPath=%%~A

:debug
echo LINE=%Line%
echo LOGPATH=%LogPath%

In C:/Temp\config.cfg, enter (exactly as typed):

-LOG "C:/Temp\Some Directory Path\With Spaces\So Path\Is Quoted"

To cause the first bit to fail, just replace -LOG with -xLOG in the
config file.

No matter how I code this (replace ### with x, etc), the if statement
always evaluates to true.

I want the final LogPath to be C:/Temp\Some Directory Path\With Spaces
\So Path\Is Quoted (without double quotes)

Thanks,
Scott
 
P

Pegasus [MVP]

Flightless Bird
"Scott Bass" wrote:

> I'm still having problems getting this to work. Here is my test
> script:
>
> set config=C:/Temp\config.cfg
>
> set Line=###
> for /F "delims=" %%A in ('type "%config%" ^| find /i "-log "') do set
> Line=%%A
> echo %Line%
>
> if ###==%Line% (
> echo ERROR: Unable to determine logs directory from config file.
> goto debug
> )
>
> set Line=%Line:-log=%
> for /F "delims=" %%A in ('echo %Line%') do set LogPath=%%~A
>
> :debug
> echo LINE=%Line%
> echo LOGPATH=%LogPath%
>
> In C:/Temp\config.cfg, enter (exactly as typed):
>
> -LOG "C:/Temp\Some Directory Path\With Spaces\So Path\Is Quoted"
>
> To cause the first bit to fail, just replace -LOG with -xLOG in the
> config file.
>
> No matter how I code this (replace ### with x, etc), the if statement
> always evaluates to true.
>
> I want the final LogPath to be C:/Temp\Some Directory Path\With Spaces
> \So Path\Is Quoted (without double quotes)
>
> Thanks,
> Scott


Welcome to the wonderful world of advanced batch files. They are a bit of a
black art - you often do not know in advance what to expect and you need to
experiment until you get it just right. This is why I prefer VB Scripts, in
particular when I need a robust solution.
I do not know why your batch file should fail the "if" statement. Here is a
modified version that works on my machine.
set config=d:/Temp\test.txt
set Line=###
for /F "delims=" %%A in ('type "%config%" ^| find /i "-log "') do set Line=%%A
echo %Line%

if ###==%Line% goto debug
set Line=%Line:-log=%
for /F "delims=" %%A in ('echo %Line%') do set LogPath=%%~A
echo LOGPATH=%LogPath%
goto :eof

:debug
echo ERROR: Unable to determine logs directory from config file.
echo LINE=%Line%
echo LOGPATH=%LogPath%
 
P

Pegasus [MVP]

Flightless Bird
Here is a robust hybrid solution that is not subject to any black magic:
@echo off
set sKey="-Log "
set sLogname="d:/temp\test.txt"
set Scr="%temp%\TempVBS.vbs"
set VB=echo^>^>%Scr%
cd 1>nul 2>%Scr%
%VB% Set oFSO = CreateObject("Scripting.FileSystemObject")
%VB% Set oFile = oFSO.OpenTextFile(%sLogName%)
%VB% bfound = False
%VB% While Not oFile.AtEndOfStream And Not bfound
%VB% sLine = oFile.ReadLine
%VB% If InStr(1, sLine, %sKey%, 1) = 1 Then
%VB% sLine = Trim(Mid(sLine, 5))
%VB% bfound = True
%VB% End If
%VB% Wend
%VB% oFile.Close
%VB% If bfound _
%VB% Then WScript.Echo sLine _
%VB% Else WScript.Echo "Keyword", %sKey%, "not found"
cscript //nologo %Scr%
del %Scr%
 
M

Mark Blain

Flightless Bird
For future reference, a more specific place to ask questions about
advanced Windows batch scripting is
<news:alt.msdos.batch.nt>
 
H

HeyBub

Flightless Bird
Scott Bass wrote:
>
> Rhetorical questions not requiring a reply: Wasn't Windows 95 just
> slapped on top of DOS?


Yes, as was Windows 1, Win 2, Win3, Win 98 and their variants.


> Does Windows XP still have a boot option to
> boot to DOS mode?


No. In spite of the name, Win XP is a continuation of the Windows NT
dynasty, not the plain Windows line.

> Don't some low level disk utilities require a
> Windows machine to boot into DOS mode?


None that come with XP.
 
Top