1.

Solve : For Loop + Set Command need helps?

Answer» <html><body><p>Hi All,<br/><br/>Currently run a small project and need a bit help on the DOS programming.... Please advice!<br/><br/>Have a text file contain the following lines:<br/>StrFile.txt<br/>ABC12345:0000121<br/>ABC12345:0000122<br/>ABC12345:0000123<br/>ABC22345:0012121<br/>ABC22345:0021212<br/>ABC32345:1212123<br/>ABC32346:2123333<br/>.....<br/><br/>Hope can transform it into:<br/>ABC12345:0000121:0000122:0000123<br/>ABC22345:0012121:0021212<br/>ABC32345:1212123<br/>ABC32346:2123333<br/><br/>======================================================<br/>Set tmpString=<br/>Set tmp=<br/><br/>FOR /F "tokens=1,2 delims=:" %%i IN (StrFile.txt) DO (<br/>   if %%i EQU %tmp% (<br/>      SET tmp=%%i<br/>      SET tmpString=%tmpString%:%%j<br/>   ) ELSE (<br/>      ECHO %tmpString% &gt;&gt; output.txt<br/>      SET tmp=%%i<br/>      SET tmpString=%%i:%%j<br/>   )<br/>)   <br/><br/>after running this batch file, get an error result...... :-(<br/>C:\&gt;Group.cmd<br/>C:\&gt;Set tmpString=<br/>C:\&gt;Set tmp=<br/>The syntax of the command is incorrect.<br/>C:\&gt;   if %i EQU  (<br/><br/>It seem something wrong with my For Loop.<br/><br/><br/>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. <a href="https://interviewquestions.tuteehub.com/tag/also-373387" style="font-weight:bold;" target="_blank" title="Click to know more about ALSO">ALSO</a> (crucially) you do not <a href="https://interviewquestions.tuteehub.com/tag/know-534065" style="font-weight:bold;" target="_blank" title="Click to know more about KNOW">KNOW</a> enough about batch file syntax, mainly delayed expansion of variables. (Google it) But also how IF tests work.<br/><br/>It seems to me that what you want to is this:<br/><br/>process a text file laid out like this<br/><br/>a:1<br/>a:2<br/>a:3<br/>b:1<br/>b:2<br/>c:3<br/>d:2<br/><br/>etc<br/><br/>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<br/><br/>a:1:2:3<br/>b:1:2<br/>c:3<br/>d:2<br/><br/>However your code is always going to fail, not because of the FOR command itself, but because the first time around the loop your <a href="https://interviewquestions.tuteehub.com/tag/variable-772077" style="font-weight:bold;" target="_blank" title="Click to know more about VARIABLE">VARIABLE</a> %tmp% is going to be blank and the IF test is in the <a href="https://interviewquestions.tuteehub.com/tag/format-11876" style="font-weight:bold;" target="_blank" title="Click to know more about FORMAT">FORMAT</a> IF v1 EQU v2. Because v2 expands to nothing the test becomes <br/><br/>IF v1 EQU<br/><br/>that is, no right hand side. This is a violation and caused your error.<br/><br/>you can avoid this by doing something like this<br/><br/>IF "v1" EQU "v2"<br/><br/>But it is always better to get the logic right <em>before</em> 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 <a href="https://interviewquestions.tuteehub.com/tag/important-1038039" style="font-weight:bold;" target="_blank" title="Click to know more about IMPORTANT">IMPORTANT</a> point in this post.)<br/><br/>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. <br/><br/>The code below appears to do what you want. <br/><br/> Code: <a>[Select]</a>echo off<br/>setlocal enabledelayedexpansion<br/><br/>REM you may not need this but<br/>REM it seemed appropriate<br/>if exist output.txt del output.txt<br/><br/>set /p firstline=&lt;Strfile.txt<br/>FOR /F "tokens=1,2 delims=:" %%i IN ("%firstline%") DO set token1=%%i&amp;set token2=%%j<br/>set buildline=%token1%:%token2%<br/>set teststring=%token1%<br/>FOR /F "skip=1 tokens=1,2 delims=:" %%i IN (StrFile.txt) DO (<br/>   if %%i EQU !teststring! (<br/>      SET buildline=!buildline!:%%j<br/>   ) ELSE (<br/>      ECHO !buildline!&gt;&gt;output.txt<br/>      SET teststring=%%i<br/>      SET buildline=%%i:%%j<br/>   )<br/>)  <br/>essentially the logic of the script is:<br/><br/>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:<br/><br/>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. <br/><br/>Now, for each line after that, until the end of the input file is reached:<br/><br/>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.<br/>OP , get a good file processing tool like<a href="http://gnuwin32.sourceforge.net/packages/gawk.htm"> gawk (for windows)</a>, and use this one liner<br/><br/> Code: <a>[Select]</a>c:\&gt; gawk -F":" "{a[$1]=a[$1]\":\"$2}END{for(i in a) print i a[i]}" file<br/>ABC32346:2123333<br/>ABC22345:0012121:0021212<br/>ABC12345:0000121:0000122:0000123<br/>ABC32345:1212123<br/><br/>Of course, if you have Perl/Python, they can do the job with ease as well.<br/>I made a typo before.<br/><br/>essentially the logic of the script is:<br/><br/>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:<br/><br/>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.<br/><br/>Now, for each line after that, until the end of the input file is reached:<br/><br/>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.<br/><br/> Code: <a>[Select]</a><br/>Echo Off<br/>Setlocal Enabledelayedexpansion<br/>Set True=1<br/>Set False=0<br/>If Exist Output.Txt Del Output.Txt<br/><br/>Set /P Firstline=&lt;Strfile.Txt<br/><br/>For /F "Tokens=1,2 Delims=:" %%I In ("%Firstline%") Do (<br/>   Set Part1=%%I<br/>   Set Part2=%%J<br/>   )<br/><br/>Set Buildline=%Part1%:%Part2%<br/>Set Teststring=%Part1%<br/>Set Writeflag=%False%<br/>Set Changed=%False%<br/><br/>For /F "Skip=1 Tokens=1,2 Delims=:" %%I In (Strfile.Txt) Do (<br/>   Set Part1=%%I<br/>   Set Part2=%%J<br/>   If Not !Part1! Equ !Teststring! Set Changed=%True%<br/>   If !Changed! Equ %True% (<br/>      Echo !Buildline!&gt;&gt;Output.Txt<br/>      Set Teststring=!Part1!<br/>      Set Buildline=!Part1!:!Part2!<br/>      Set Writeflag=%True%<br/>      Set Changed=%False%<br/>   ) Else (<br/>      Set Buildline=!Buildline!:!Part2!<br/>      Set Writeflag=%False%<br/>   )<br/>) <br/> <br/>If %Writeflag% Equ %False% Echo !Buildline!&gt;&gt;Output.Txt<br/><br/>Echo.<br/>Echo Input File:<br/>Type Strfile.Txt<br/>Echo.<br/>Echo Output File:<br/>Type Output.Txt<br/>Echo.<br/>Pause<br/><br/>here's my output<br/><br/> Code: <a>[Select]</a>C:\test&gt;test.bat<br/><br/>Input File:<br/>ABC12345:0000121<br/>ABC12345:0000122<br/>ABC12345:0000123<br/>ABC22345:0012121<br/>ABC22345:0021212<br/>ABC32345:1212123<br/>ABC32346:2123333<br/><br/>Output File:<br/>ABC12345:0000121:0000122:0000123<br/>ABC22345:0012121:0021212<br/>ABC32345:1212123<br/><br/>ABC32346:2123333 is missing.. or what have i done wrong?Thanks Man!<br/><br/>Your guidance will be appreciated. Thank you!<br/>Since I am not good at programing.... it took some time to understand the code...kekek<br/><br/></p></body></html>


Discussion

No Comment Found