Batch File not capturing the full line due to spaces

Simon336697
Simon336697 used Ask the Experts™
on
Hi guys hope you are well and can help.

I have a batch file that is trying to read a text file.
This text file has one column of user names, with each name being in format:

Firstname Lastname

So, a scenario might be:

script.bat users.txt

If is users.txt, we have:

--------------------------------------------------- users.txt
Simon Jones
Peter Tims
Sue Morgan

When I run the batch file, we get

Simon
Peter
Sue

So, what Im trying to do is to capture the entire line, but it seems that it only captures the firsname and stops at the space. Note that each name could have multiple spaces.
Im just not sure how to modify my batch file to cater for spaces.

Any help greatly appreciated.

@echo off
if [%1]==[] (
echo useage: script [computers.txt]
echo         computers.txt contains hostname or ip address, one per line.
goto :eof
)
rem for each line in textfile
for /f %%c in (%1) do (
  call :GETINFO %%c
)
goto :eof
 
:GETINFO
echo %1

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
Try this:

@echo off
if [%1]==[] (
echo useage: script [computers.txt]
echo         computers.txt contains hostname or ip address, one per line.
goto :eof
)
rem for each line in textfile
for /f "tokens=*" %%c in (%1) do (
  call :GETINFO %%c
)
goto :eof
 
:GETINFO
echo %1

Author

Commented:
Hi bill, thanks so much, but this still does not echo the entire line, and stops at first space.
Steven CarnahanAssistant Vice President\Network Manager

Commented:
Modification of bill's script:

@echo off
if [%1]==[] (
echo useage: script [computers.txt]
echo         computers.txt contains hostname or ip address, one per line.
goto :eof
)
rem for each line in textfile
for /f "tokens=*" %%c in (%1) do (
  echo %%c
)
goto :eof
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

Steven CarnahanAssistant Vice President\Network Manager

Commented:
Or following the original using bill's script:

@echo off
if [%1]==[] (
echo useage: script [computers.txt]
echo         computers.txt contains hostname or ip address, one per line.
goto :eof
)
rem for each line in textfile
for /f "tokens=*" %%c in (%1) do (
call :GETINFO %%c
)
goto :eof

:GETINFO
echo %1 %2
Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
Doh, silly me, try this:

@echo off
if [%1]==[] (
echo useage: script [computers.txt]
echo         computers.txt contains hostname or ip address, one per line.
goto :eof
)
rem for each line in textfile
for /f "tokens=*" %%c in (%1) do (
  call :GETINFO "%%c"
)
goto :eof
 
:GETINFO
echo %~1

~bp
Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
pony10us!, how ya been...

~bp
Steven CarnahanAssistant Vice President\Network Manager

Commented:
pretty good.  Just had to jump in on one of your answers to say hey.   :)  How you been?

Speaking of which, what is the difference between:

echo %1 %2  and echo %~1

Is it just that the first will only return the first two "items" and the second will return the entire string regardless of count?
IT / Software Engineering Consultant
Top Expert 2016
Commented:
==> Simon336697

So let's talk about what's going on here.  In your original script there were really 2 problems.  First, the FOR command you were using was:

for /f %%c in (%1) do (

This uses the default field separators and such and so was breaking the input line apart on space ot tab, and placing the first token in %%c.  If you do FOR /? at a command line you will notice that there are some modifiers that can be used with the FOR command to change default behavior.  So I proposed the following:

for /f "tokens=*" %%c in (%1) do (

This has the effect of putting the entire line in the first FOR loop variable, in your case %%c.  This is because the * in the tokens option says to place the entire remaining line in the next variable.  Since we only used the *, and no token numbers, the whole line goes into the first variable.

So at this point we have the entire line in the %%c variable.  Now you had the following bits of code:

call :GETINFO %%c
. .
:GETINFO
echo %1

The CALL statement allows multiple parms to be passed to a called routine, and it looks at the command line after the name of the routine to call, and parses it up at spaces, placing each in a different parameter to the called routine.  Since you have a first name and a last name in %%c, with a space between them, the CALL treated them as two parms when passing to :GETINFO.  So in GETINFO, %1 would have had the first name, and %2 would have had the last name.  To get around this and pass everything in %%c as a single parm, we need to quote it, as in:

call :GETINFO "%%c"

You need to keep in mind though that while %1 in GETINFO will now have the entire line in it, it will also have the quotes around the string.  Typically we then reference the variable in GETINGO as %~1, the ~ says to remove any surrounding quotes if found.  So %~1 will return the entire line without the quotes.

For now I'll assume you want %1 to be the full line (both names), let me know if that's not true.

~bp
Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
==> pony10us

See my last post, let me know if that answers your last question.

I'm doing well, haven't been as active on EE the last few weeks, had some oral surgery, then a business trip, etc, so not as active here.  But still like to try and lend a hand when I see a question and there isn't already someone helping.

~bp
Steven CarnahanAssistant Vice President\Network Manager

Commented:
@billprew

Very good explanation. Once again I learned something. I didn't know about the quotes and ~ functions.   I miss our conversations about methods.  :)  

Author

Commented:
Hi bill that is so awesome what you have done here.

Author

Commented:
Bill,

If the file you were reading had the following:

======================================= file.txt
   Joe Bloggs
Simon Jones
   Doctor van Dough
Peter Stevens  <spaces here at the end>

and you wanted to return

Joe Bloggs
Simon Jones
Doctor van Dough
Peter Stevens (with no spaces at the end)

How could you return this by removing the starting blank spaces and trailing blank spaces?

If you want me to start another question, very happy to as you have been awesome.

Ill award you the points now in advance. Thanks so much again.

Author

Commented:
Bill your explanation is very very impressive. Thanks so much.
Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
Give this a try, I think it should do what you are looking for:

@echo off
if [%1]==[] (
echo useage: script [computers.txt]
echo         computers.txt contains hostname or ip address, one per line.
goto :eof
)
rem for each line in textfile
for /f "tokens=*" %%c in (%1) do (
  call :GETINFO %%c
)
goto :eof
 
:GETINFO
echo %*
exit /b

~bp

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial