1.

Solve : Seeking help on DOS command (SET command)?

Answer»

Hi All,

I am here to seek for any help on the DOS command!

I have a text file which contains 100+ which looks like the following lines:

[Inv.txt]
Peter;STD:17/09/200718/09/2012214;NBD:17/09/200818/09/20100;POW:17/09/200818/09/20100
Paul;STD:18/07/200719/07/2012153;POW:18/07/200819/07/20100;NBD:18/07/200819/07/20100
Mary;NBD:25/12/201026/12/2012312;POW:25/12/201026/12/2012312
John;STD:17/09/200718/09/2012214;POW:17/09/200818/09/20100;NBD:17/09/200818/09/20100
Jerry;POW:23/10/201124/10/2012250;NBD:23/10/201124/10/2012250
Alex;NBD:21/04/201122/04/2013430;POW:21/04/201222/04/2013366;POW:21/04/201022/04/201265
Alice;STD:23/04/200424/04/20090;NBD:23/04/200424/04/20070;POW:23/04/200424/04/20070

On each line, I only interesting on some information which start with POW;
[Result.txt]
Peter;POW:17/09/200818/09/20100
Paul;POW:18/07/200819/07/20100
Mary;POW:25/12/201026/12/2012312
John;POW:17/09/200818/09/20100
Jerry;POW:23/10/201124/10/2012250
Alex;POW:21/04/201222/04/2013366;POW:21/04/201022/04/201265
Alice;POW:23/04/200424/04/20070

I try to run the code:
For /F "tokens=1-8 delims=;" %%a in (inv.txt) Do (
SET STR== %%a
ECHO %%b > tmp.tmp
FINDSTR "^P" tmp.tmp
IF !ERRORLEVEL! EQU 0 SET STR=%STR%;%%b

ECHO %%c > tmp.tmp
FINDSTR "^P" tmp.tmp
IF !ERRORLEVEL! EQU 0 SET STR=%STR%;%%c

ECHO %%d > tmp.tmp
FINDSTR "^P" tmp.tmp
IF !ERRORLEVEL! EQU 0 SET STR=%STR%;%%d

ECHO %%e > tmp.tmp
FINDSTR "^P" tmp.tmp
IF !ERRORLEVEL! EQU 0 SET STR=%STR%;%%e

ECHO %%f > tmp.tmp
FINDSTR "^P" tmp.tmp
IF !ERRORLEVEL! EQU 0 SET STR=%STR%;%%f

ECHO %%g > tmp.tmp
FINDSTR "^P" tmp.tmp
IF !ERRORLEVEL! EQU 0 SET STR=%STR%;%%g

ECHO %%h > tmp.tmp
FINDSTR "^P" tmp.tmp
IF !ERRORLEVEL! EQU 0 SET STR=%STR%;%%h

ECHO %STR% >>Result.txt
)


The result was not right (It only has the first valuable "Peter" in the result.txt)
 and I figure out the SET command is not working....
Your guidance will be appreciated. Thank you!So are you basically saying their will never be more than 8 tokens?  Meaning 8 fields separated by a semi colon?
Your basic problem right now is that the POW information is never the same token(FIELD).
So you basically have to test each Token to see if the first 3 characters equal POW.Kind of WONDERING why you are confused with the DelayedExpansion.
You are using it with the ERRORLEVEL but you don't use it with your STR variable.  You do realize that you need to do it with both.  You ALSO did not explicitly enable delayed expansion anywhere in your script.

You also don't have to write out the LOOP variable to a file first.  Just echo the variable and pipe the output to the FINDSTR command.
ECHO %%g |FINDSTR "^P" Quote

SET STR== %%a

Lose those double equals

You could really shorten things up by doing this.
Code: [Select]ECHO %%b |FINDSTR "^P" &&SET STR=!STR!;%%bAnother approach would be to not use the set command at all. Clear, concise and about as simple as it gets:

Code: [Select]echo off
setlocal

for /f "tokens=1-4 delims=;" %%i in ('findstr /i "pow" inv.txt') do (
  echo %%j | find /i "pow" > nul && echo %%i;%%j
  echo %%k | find /i "pow" > nul && echo %%i;%%k
  echo %%l | find /i "pow" > nul && echo %%i;%%l
)

Note: Alex has two POW parameters and is therefore listed twice.

Good luck. 


Quote from: Sidewinder on March 01, 2012, 01:03:51 PM
Another approach would be to not use the set command at all. Clear, concise and about as simple as it gets:

Code: [Select]echo off
setlocal

for /f "tokens=1-4 delims=;" %%i in ('findstr /i "pow" inv.txt') do (
  echo %%j | find /i "pow" > nul && echo %%i;%%j
  echo %%k | find /i "pow" > nul && echo %%i;%%k
  echo %%l | find /i "pow" > nul && echo %%i;%%l
)

Note: Alex has two POW parameters and is therefore listed twice.

Good luck. 
But this doesn't work for the way he wants his output. Quote
But this doesn't work for the way he wants his output.

Code: [Select]echo off
setlocal

if exist result.txt del result.txt

for /f "tokens=1-4 delims=;" %%i in ('findstr /i "pow" inv.txt') do (
  echo %%j | find /i "pow" > nul && echo %%i;%%j >> result.txt
  echo %%k | find /i "pow" > nul && echo %%i;%%k >> result.txt
  echo %%l | find /i "pow" > nul && echo %%i;%%l >> result.txt
)

 



Quote from: Squashman on March 01, 2012, 09:51:34 AM
You could really shorten things up by doing this.
Code: [Select]ECHO %%b |FINDSTR "^P" &&SET STR=!STR!;%%b

Thanks for this tip, it is sample but powerful!Hi Squashman & Sidewinder;

First of all, thanks for your advice!

May be I do not make my question clear enough..... I have a CSV file :
- contain 100+ lines which have multi tokens (so some times it contains the key word "POW" more than once!)
- the first token is an index so it must remind at the beginning of the line!
- wants to show each entries like
   index;POW:XXXXXXXX;POW:XXXXXXXX;POW..... <- if 2rd or 3th or 4th .....found!

I try to store/update the new token into the variable so it can ECHO the result at the same line.
Also rewrite the code and still the %STR% is not change the way I want

======================================================================
setlocal

if exist result.txt del result.txt
For /F "tokens=1-8 delims=;" %%a in (inv.txt) Do (
   ::Store the first token into the variable
   SET STR=%%a
   ::Test each token; if found start with "P" add it into %STR%
   ECHO %%b |FINDSTR "^P" &&SET STR=!STR!;%%b
   ECHO %%c |FINDSTR "^P" &&SET STR=!STR!;%%c
   ECHO %%d |FINDSTR "^P" &&SET STR=!STR!;%%d
   ECHO %%e |FINDSTR "^P" &&SET STR=!STR!;%%e
   ECHO %%f |FINDSTR "^P" &&SET STR=!STR!;%%f
   ECHO %%g |FINDSTR "^P" &&SET STR=!STR!;%%g
   ECHO %%h |FINDSTR "^P" &&SET STR=!STR!;%%h
   ::Output the string into the final result
   ECHO %STR% >> result.txt
)
===================================================
After run the batch; the result.txt only contains the index :-(
%Peter
%Paul
%Mary
%John
%Jerry
%Alex
%Alice

The STR will not update and seem the SET command is not working at all.....

Ok....after do some search on the delayedexpansion....all I need is add "Setlocal enabledelayedexpansion" at the beginning, and it work!  Quote from: qzero on March 01, 2012, 09:27:52 PM
all I need is add "Setlocal enabledelayedexpansion" at the beginning, and it work! 

Maybe. You need to change %STR% to !STR! everywhere inside the loop.

you missed one...

Quote
ECHO %STR% >> result.txt

Also (VERY IMPORTANT) - You must not use double-colons ( to start comments inside a loop. It will break the code. Double colons are broken labels. They are unofficial, undocumented, deprecated, not supported, bad, wrong, etc. (Yes I know they were OK to use in MS-DOS. This is not MS-DOS). Use REM.





Quote
- the first token is an index so it must remind at the beginning of the line!
- wants to show each entries like

I realize I'm not smarter then a fifth grader, but I can't seem to locate the index you WROTE about.

This second try is not nearly as elegant as my first but is more generic .It will scan each line for all keywords present, filtering out POW for processing.

Code: [Select]echo off
setlocal enabledelayedexpansion

for /f "tokens=1* delims=;" %%i in (inv.txt) do (
  set keyword=
  call :keywords %%j
  echo %%i!keyword!

goto :eof

:keywords
  if .%1==. goto :eof
  echo %1 | find /i "pow" > nul && set keyword=%keyword%;%1
  shift
  goto keywords

If you want to push the output into a file, add redirection to the echo STATEMENT in the for loop.

Hope this works for you.


Discussion

No Comment Found