1.

Solve : For Loop + Set Command need helps?

Answer»

Hi All,

Currently run a small project and need a bit help on the DOS programming.... Please advice!

Have a text file contain the following lines:
StrFile.txt
ABC12345:0000121
ABC12345:0000122
ABC12345:0000123
ABC22345:0012121
ABC22345:0021212
ABC32345:1212123
ABC32346:2123333
.....

Hope can transform it into:
ABC12345:0000121:0000122:0000123
ABC22345:0012121:0021212
ABC32345:1212123
ABC32346:2123333

======================================================
Set tmpString=
Set tmp=

FOR /F "tokens=1,2 delims=:" %%i IN (StrFile.txt) DO (
   if %%i EQU %tmp% (
      SET tmp=%%i
      SET tmpString=%tmpString%:%%j
   ) ELSE (
      ECHO %tmpString% >> output.txt
      SET tmp=%%i
      SET tmpString=%%i:%%j
   )
)  

after running this batch file, get an error result...... :-(
C:\>Group.cmd
C:\>Set tmpString=
C:\>Set tmp=
The syntax of the command is incorrect.
C:\>   if %i EQU  (

It seem something wrong with my For Loop.


It's not the FOR loop that is the problem, I would say the problem is more that you have not thought enough about the logic of the process that you want to do. ALSO (crucially) you do not KNOW enough about batch file syntax, mainly delayed expansion of variables. (Google it) But also how IF tests work.

It seems to me that what you want to is this:

process a text file laid out like this

a:1
a:2
a:3
b:1
b:2
c:3
d:2

etc

and you want to take all the lines with the same first part and make them into 1 line starting with the first part and then all of the second parts in order separated by colons thus

a:1:2:3
b:1:2
c:3
d:2

However your code is always going to fail, not because of the FOR command itself, but because the first time around the loop your VARIABLE %tmp% is going to be blank and the IF test is in the FORMAT IF v1 EQU v2. Because v2 expands to nothing the test becomes

IF v1 EQU

that is, no right hand side. This is a violation and caused your error.

you can avoid this by doing something like this

IF "v1" EQU "v2"

But it is always better to get the logic right before you start coding! It is no good having half an idea of how your script will work and hoping that it will get fixed in the editor! (This is the most IMPORTANT point in this post.)

You need to get the first line of the text file before you do any loop stuff. You can use set /p to get the first line.

The code below appears to do what you want.

Code: [Select]echo off
setlocal enabledelayedexpansion

REM you may not need this but
REM it seemed appropriate
if exist output.txt del output.txt

set /p firstline=<Strfile.txt
FOR /F "tokens=1,2 delims=:" %%i IN ("%firstline%") DO set token1=%%i&set token2=%%j
set buildline=%token1%:%token2%
set teststring=%token1%
FOR /F "skip=1 tokens=1,2 delims=:" %%i IN (StrFile.txt) DO (
   if %%i EQU !teststring! (
      SET buildline=!buildline!:%%j
   ) ELSE (
      ECHO !buildline!>>output.txt
      SET teststring=%%i
      SET buildline=%%i:%%j
   )

essentially the logic of the script is:

the input file has lines which follow the format part:part2. It is required, for each sequence of one or more lines starting with the same part1, to produce one line which starts with part1, then a colon, then however many part2s there are, separated by colons. The script would do something like this:

Look at the first line of the input file. Get part1 and part2 into separate variables. Start building the first output line using part1, a colon and part2.

Now, for each line after that, until the end of the input file is reached:

Get part1 and part2 into separate variables. Check if part1 has changed since the previously read input line. If it has not changed, add a colon and part2 to the output line. If part1 has changed, write the output line to the output file in append mode, and then start a new output line using the new part1, a colon and part2.
OP , get a good file processing tool like gawk (for windows), and use this one liner

Code: [Select]c:\> gawk -F":" "{a[$1]=a[$1]\":\"$2}END{for(i in a) print i a[i]}" file
ABC32346:2123333
ABC22345:0012121:0021212
ABC12345:0000121:0000122:0000123
ABC32345:1212123

Of course, if you have Perl/Python, they can do the job with ease as well.
I made a typo before.

essentially the logic of the script is:

the input file has lines which follow the format part1:part2. It is required, for each sequence of one or more lines starting with the same part1, to produce one line which starts with part1, then a colon, then however many part2s there are, separated by colons. The script would do something like this:

Look at the first line of the input file. Get part1 and part2 into separate variables. Start building the first output line using part1, a colon and part2.

Now, for each line after that, until the end of the input file is reached:

Get part1 and part2 into separate variables. Check if part1 has changed since the previously read input line. If it has not changed, add a colon and part2 to the output line. If part1 has changed, write the output line to the output file in append mode, and then start a new output line using the new part1, a colon and part2.They say pride comes before a fall - and I was so concerned with delivering a lecture that I didn't see that my code has one big flaw, namely that it only outputs a line when the first part of the input line changes. if an input file just consists of one line, or of multiple lines with the same first part, then it would never output anything. This should be a lesson to me. I will fix it it tomorrow. because we are just now going to watch a film, "Villa Amalia" with Isabelle Huppert. And drink some red wine.

Code: [Select]
Echo Off
Setlocal Enabledelayedexpansion
Set True=1
Set False=0
If Exist Output.Txt Del Output.Txt

Set /P Firstline=<Strfile.Txt

For /F "Tokens=1,2 Delims=:" %%I In ("%Firstline%") Do (
   Set Part1=%%I
   Set Part2=%%J
   )

Set Buildline=%Part1%:%Part2%
Set Teststring=%Part1%
Set Writeflag=%False%
Set Changed=%False%

For /F "Skip=1 Tokens=1,2 Delims=:" %%I In (Strfile.Txt) Do (
   Set Part1=%%I
   Set Part2=%%J
   If Not !Part1! Equ !Teststring! Set Changed=%True%
   If !Changed! Equ %True% (
      Echo !Buildline!>>Output.Txt
      Set Teststring=!Part1!
      Set Buildline=!Part1!:!Part2!
      Set Writeflag=%True%
      Set Changed=%False%
   ) Else (
      Set Buildline=!Buildline!:!Part2!
      Set Writeflag=%False%
   )
)
 
If %Writeflag% Equ %False% Echo !Buildline!>>Output.Txt

Echo.
Echo Input File:
Type Strfile.Txt
Echo.
Echo Output File:
Type Output.Txt
Echo.
Pause

here's my output

Code: [Select]C:\test>test.bat

Input File:
ABC12345:0000121
ABC12345:0000122
ABC12345:0000123
ABC22345:0012121
ABC22345:0021212
ABC32345:1212123
ABC32346:2123333

Output File:
ABC12345:0000121:0000122:0000123
ABC22345:0012121:0021212
ABC32345:1212123

ABC32346:2123333 is missing.. or what have i done wrong?Thanks Man!

Your guidance will be appreciated. Thank you!
Since I am not good at programing.... it took some time to understand the code...kekek



Discussion

No Comment Found