Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Parse Field

89 views
Skip to first unread message

Hank

unread,
Apr 30, 2010, 9:16:42 AM4/30/10
to
I have a temp file (find.tmp) that contains the following string:

INW-SAM servername01 9999 3032 RUNNING Apr 27 17:22:07 2010

I'm trying to extract the 4th field, which is a PID, (3032) so I can
pass the PID to a kill process command. Below is the command I'm
using to trying to extract the data with:

for /f "tokens=4 delims=" %%G in (find.tmp) do @echo G: %%G


However, my logic (or lack of understanding of tokens) is wrong. Any
help is appreciated!

foxidrive

unread,
Apr 30, 2010, 9:51:04 AM4/30/10
to

"tokens=4 delims= "

You need to set the delims to a space or tab as the case might be - or
remove the delims= entirely as the default is already space and tab.


--
Regards,
Mic

Thomas Langer

unread,
Apr 30, 2010, 10:04:18 AM4/30/10
to

"Hank" <hammerin...@gmail.com> schrieb im Newsbeitrag
news:a476ca63-8bb6-40cb...@j20g2000prn.googlegroups.com...

or

for /f "tokens=4" %%G in (find.tmp) do @echo G: %%G


work both. You must specify the blank char when you use delims keyword or
you must omit delims keyword because space char is delimter by default.

Regards
Thomas


Matthias Tacke

unread,
Apr 30, 2010, 1:26:02 PM4/30/10
to

Hi Hank,

well the tokens=4 is right but by disabling the delimiters all content
will fit in token 1 which you skipped.

Since space is a standard delimiter you simply can omit the delims=
specifier.

--
Regards
Matthias

Hank

unread,
May 10, 2010, 4:15:33 PM5/10/10
to
Thanks everyone! Another question. I'm now trying to kill the task
with my code below, but I'm getting "invalid syntax" for the taskkill
command:

for /f "tokens=4 delims= " %%G in (find.tmp) SET PID=%%G
TASKKILL /PID %PID%

Thanks for any help!
Hank

foxidrive

unread,
May 10, 2010, 4:54:15 PM5/10/10
to

You left the DO keyword out of the for in do command - is that a copy and
paste?


--
Regards,
Mic

Matthias Tacke

unread,
May 10, 2010, 4:56:04 PM5/10/10
to
Am 2010-05-10 22:15, schrieb Hank:
> Thanks everyone! Another question. I'm now trying to kill the task
> with my code below, but I'm getting "invalid syntax" for the taskkill
> command:
>
> for /f "tokens=4 delims= " %%G in (find.tmp) SET PID=%%G
> TASKKILL /PID %PID%
>

Hi Hank,

if you use an nonexistent Pid you get a different error message,

Looks like PID is not defined, you could check it prior to using it,

But better you'd don't use a canned PID from a file but get the actual
PID with tasklist or whatever you used to generate find.tmp.

--
Regards
Matthias

Hank

unread,
May 11, 2010, 9:27:34 AM5/11/10
to
I'm getting the PID successfully, but having trouble passing it to the
taskkill command. Here's the output from the batch file attempt:

C:\restart_sm_service
1968 set PID=1968
ERROR: Invalid syntax. Value expected for '/pid'.
Type "TASKKILL /?" for usage.

Matthias Tacke

unread,
May 11, 2010, 10:10:48 AM5/11/10
to
Am 2010-05-11 15:27, schrieb Hank:
> I'm getting the PID successfully, but having trouble passing it to the
> taskkill command. Here's the output from the batch file attempt:
>
> C:\restart_sm_service
> 1968 set PID=1968
> ERROR: Invalid syntax. Value expected for '/pid'.
> Type "TASKKILL /?" for usage.
>

Did you follow Mic's tip and insert the missing do?

What is that number 1968 in front of the set?

Please post the batch part which generates the temp file also,
Maybe we can construe a parsing for /f which gets the pid directly.

--
Regards
Matthias

Hank

unread,
May 11, 2010, 10:42:21 AM5/11/10
to
I'm not sure where the DO command is missing. Here's the complete
batch file. Note that I'm pulling the PID from a third-party
application (hence brcontrol).

@echo off
d:
cd d:\incharge7\sam\smarts\bin
brcontrol>c:\temp\brcontrol.tmp
c:
cd \temp
findstr /c:"INW-SAM ENPEFRSMA01.afspdev 9999 "
brcontrol.tmp>find.tmp
for /f "tokens=4 delims= " %%G in (find.tmp) do @echo %%G set PID=%%G
do @echo %%G
taskkill /pid %PID%

Matthias Tacke

unread,
May 11, 2010, 11:02:04 AM5/11/10
to
Am 2010-05-11 16:42, schrieb Hank:
> I'm not sure where the DO command is missing.
The syntax can be seen at the command line with:
for /?

> Here's the complete batch file.
> Note that I'm pulling the PID from a third-party application
> (hence brcontrol).

That doesn't matter. As long as that app outputs to stdout it can be
parsed with a for /f.

Try this modified batch without temp files.

@echo off
set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
Pushd "d:\incharge7\sam\smarts\bin"


for /f "tokens=4" %%G in (

'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G
echo PID=%PID%
if Not defined PID Echo PID not defined & Pause & goto :Eof
taskkill /pid %PID%
POPD


HTH

--
Regards
Matthias

billious

unread,
May 11, 2010, 11:44:07 AM5/11/10
to


The syntax of the FOR command is

For ..options.. %%v in (list) do statement

Not sure whether this is physically on one line or two:

for /f "tokens=4 delims= " %%G in (find.tmp) do @echo %%G set PID=%%G
do @echo %%G


But it should be (as one line)

for /f "tokens=4 delims= " %%G in (find.tmp) do echo %%G&set PID=%%G&echo
%%G

* The "@" is NOT required. it merely suppresses echoing of the ECHO command
itself to screen. Normally, the first line of batch is

@echo off

which turns OFF the echoing off commands to screen - the "@" here suppresses
the echoing of this initial ECHO command

To form a compound statement, separate each individual statement by "&" on a
physical line
OR

for /f "tokens=4 delims= " %%G in (find.tmp) do (
echo %%G
set PID=%%G
echo %%G
)

Where each individual statement is on its own separate line and the set of
lines is parenthesised. The opening parenthesis must be on the same physical
line as the DO.
* You can combine statements using the "&" separator if you prefer
* The first statement may follow the opening parenthesis on the same
physical line
* The closing parenthesis may terminate the final physical line; it does not
have to be on its own line

If you have the second "do @echo %%G" on a separate physical line as it
appears from your post, then %%G is out-of-context at that point. It only
remains in-context for the "for" line (and any parenthesised statement-set
following.)

In your case, the system should have shown

1968 set PID=1968
%G

or

1968 set PID=1968 do @echo 1968

depending on where your line-break (if any) occurred. Either way, the
variable "PID" would not have been set.

Hank

unread,
May 11, 2010, 11:54:59 AM5/11/10
to
Great! It worked fine. Thanks for the helpl Matthias!

Hank

unread,
May 18, 2010, 8:50:29 AM5/18/10
to
Okay, another question. I only get to work on this maybe one hour a
week if I'm lucky, hence the sporadic questions! Anyway, I (tried) to
modify the code to look for the absence of the PID after I stop it,
but the do set command is setting it to 0. I'm missing something
obviously. Here's the code:

@echo off
set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
Pushd "d:\incharge7\sam\smarts\bin"
for /f "tokens=4" %%G in (
'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G

echo OLD-PID=%PID%

rem sm_service stop ic-sam-server

echo OLD-PID=%PID%

for /f "tokens=4" %%G in (

'tasklist /NH /fi "PID eq %PID%"'
) do set PID=%%G
if "%pid%"=="" echo No PID found & exit /b
echo NEW-PID=%PID%

> > Matthias- Hide quoted text -
>
> - Show quoted text -

foxidrive

unread,
May 18, 2010, 9:08:46 AM5/18/10
to
On Tue, 18 May 2010 05:50:29 -0700 (PDT), Hank
<hammerin...@gmail.com> wrote:

>Okay, another question. I only get to work on this maybe one hour a
>week if I'm lucky, hence the sporadic questions! Anyway, I (tried) to
>modify the code to look for the absence of the PID after I stop it,
>but the do set command is setting it to 0. I'm missing something
>obviously. Here's the code:
>
>@echo off
>set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
>Pushd "d:\incharge7\sam\smarts\bin"
>for /f "tokens=4" %%G in (
> 'brcontrol ^|findstr /I /C:%Search%'
> ) do set PID=%%G
>echo OLD-PID=%PID%
>
>rem sm_service stop ic-sam-server
>
>echo OLD-PID=%PID%
>
>for /f "tokens=4" %%G in (
> 'tasklist /NH /fi "PID eq %PID%"'
> ) do set PID=%%G
> if "%pid%"=="" echo No PID found & exit /b
>echo NEW-PID=%PID%

Try this modification:

for /f "tokens=2" %%G in (


'tasklist /NH /fi "PID eq %PID%"'
) do set PID=%%G


You were setting it to the Session# and not the PID column - but why you
are sitting the PID again, once you already have the PID?


--
Regards,
Mic

Hank

unread,
May 18, 2010, 12:28:34 PM5/18/10
to
Here's the gist of what I'm trying to do:

1. Capture the PID of a process that I need to restart.
2. Stop the process (using sm_service stop)
3. I have to now wait for the process to complete writing out its temp
files, so I'm checking to see when the process is NULL.
4. Once it's NULL, then restart the process again.

Hank

On May 18, 7:08 am, foxidrive <got...@woohoo.invalid> wrote:
> You were setting it to the Session# and not the PID column - but why you
> are sitting the PID again, once you already have the PID?
>
> --
> Regards,

> Mic- Hide quoted text -

foxidrive

unread,
May 18, 2010, 1:43:07 PM5/18/10
to
On Tue, 18 May 2010 09:28:34 -0700 (PDT), Hank
<hammerin...@gmail.com> wrote:

>Here's the gist of what I'm trying to do:
>
>1. Capture the PID of a process that I need to restart.
>2. Stop the process (using sm_service stop)
>3. I have to now wait for the process to complete writing out its temp
>files, so I'm checking to see when the process is NULL.
>4. Once it's NULL, then restart the process again.

If it's a service that you are stopping:

@echo off
net stop ic-sam-server
:loop
net start |find /i "ic-sam-server">nul && goto :loop
net start ic-sam-server


--
Regards,
Mic

Hank

unread,
May 18, 2010, 2:59:27 PM5/18/10
to
Mic,

If only it was that simple! :-) The application (SMARTS-in-Charge)
creates numerous processes called sm_server (with unique PIDs), but
each one performs a different function, hence the reason I can't just
kill the sm_server process. I have to use the sm_service stop ic-sam-
server command to stop the specific process.

On May 18, 11:43 am, foxidrive <got...@woohoo.invalid> wrote:
> On Tue, 18 May 2010 09:28:34 -0700 (PDT), Hank
>

foxidrive

unread,
May 18, 2010, 3:20:46 PM5/18/10
to
On Tue, 18 May 2010 11:59:27 -0700 (PDT), Hank
<hammerin...@gmail.com> wrote:

>On May 18, 11:43�am, foxidrive <got...@woohoo.invalid> wrote:
>> On Tue, 18 May 2010 09:28:34 -0700 (PDT), Hank
>>
>> <hammerin.hanks...@gmail.com> wrote:
>> >Here's the gist of what I'm trying to do:
>>
>> >1. Capture the PID of a process that I need to restart.
>> >2. Stop the process (using sm_service stop)
>> >3. I have to now wait for the process to complete writing out its temp
>> >files, so I'm checking to see when the process is NULL.
>> >4. Once it's NULL, then restart the process again.
>>
>> If it's a service that you are stopping:
>
>If only it was that simple! :-) The application (SMARTS-in-Charge)
>creates numerous processes called sm_server (with unique PIDs), but
>each one performs a different function, hence the reason I can't just
>kill the sm_server process. I have to use the sm_service stop ic-sam-
>server command to stop the specific process.
>

This is based on your code but the tasklist command looks for a string that
is returned to STDERR when the PID is not found.


@echo off
set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
Pushd "d:\incharge7\sam\smarts\bin"
for /f "tokens=4" %%G in (
'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G
echo OLD-PID=%PID%

rem sm_service stop ic-sam-server

:loop
tasklist /FI "PID eq %pid%" 2>&1 |find /i "INFO: No tasks">nul || (
goto :loop
)

--
Regards,
Mic

Matthias Tacke

unread,
May 18, 2010, 3:44:42 PM5/18/10
to
Am 2010-05-18 20:59, schrieb Hank:
> Mic,
>
> If only it was that simple! :-) The application (SMARTS-in-Charge)
> creates numerous processes called sm_server (with unique PIDs), but
> each one performs a different function, hence the reason I can't just
> kill the sm_server process. I have to use the sm_service stop ic-sam-
> server command to stop the specific process.

So why don't you reuse the snippet known to be working?

I stuffed it into a sub (untested)
I integrated a timeout when waiting for the service to stop.
the ping waits 2 seconds berfore retrying and the count is 30 making
one minute, change these numbers to your liking.

:: ------------------------------------------------------------------
@Echo off&Setlocal


set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "

Call :GetPid PID
If Not defined PID Echo Service not running & goto :Eof
:: stop Service
sm_service stop ic-sam-server

Set Cnt=0
:Redo
If %Cnt% GTR 30 Echo Timeout stopping service&Pause&Goto :Eof
Call :GetPid PID
if defined PID Ping -n 2 Localhost >NUL &Set /A Cnt+=1 &Goto :Redo
Echo Service(ses) are down
:: do whatever

Goto :Eof
:GetPID PID ---------------------------------------------------------
setlocal
if defined PID set "PID="


Pushd "d:\incharge7\sam\smarts\bin"
for /f "tokens=4" %%G in (
'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G

popd
Endlocal&Set "PID=%PID%"
:: ------------------------------------------------------------------

HTH

--
Regards
Matthias

Hank

unread,
May 18, 2010, 4:26:09 PM5/18/10
to
Thanks Mic. Can you explain this piece of code you're using:

2>&1 |find /i "INFO: No tasks">nul || (
goto :loop
)

foxidrive

unread,
May 18, 2010, 11:39:01 PM5/18/10
to
On Tue, 18 May 2010 13:26:09 -0700 (PDT), Hank
<hammerin...@gmail.com> wrote:

>Thanks Mic. Can you explain this piece of code you're using:
>
>2>&1 |find /i "INFO: No tasks">nul || (
>goto :loop
>)


">2&1" sends the STDERR stream to the same place that STDOUT is going.

In the above they will both be piped to FIND.

"||" and "&&" evaluate the errorlevel of the previous command and execute
the following commands. || executes on errorlevel 1 or higher and &&
executes on errorlevel 0.

In the above if the string is not found it will branch to the :loop label.

Or it should - I didn't test it.


--
Regards,
Mic

halim...@gmail.com

unread,
Sep 26, 2013, 12:10:02 PM9/26/13
to
0 new messages