Batch to output a list to delimited text

June 2, 2010 at 00:14:44
Specs: Windows XP, 3GHz/1GB
I tried to convert a list (in .txt) to delimited text (also in .txt) but to no avail. I need to use batch.

The source text file is like this:

111111
a1
a2
a3

222222
b1
b2
b3

333333
c1
c2
c3

and so on

The result text should be:

111111,a1,a2,a3
222222,b1,b2,b3
333333,c1,c2,c3

Anyone can help?


See More: Batch to output a list to delimited text

Report •

#1
June 2, 2010 at 00:45:28
Assuming that the new lines are always there and none of the "1111.."
header lines start with "=":


edit: Also forgot none of the lines in the file can start with "]".

for /f "skip=2 tokens=1* delims=]" %%a in (' find /v /n "" "yourfile.txt" ') do (
    if "%%b"=="" (
        >> "newfile.txt" echo.
        set comma=
    ) else (
        if defined comma (
            >> "newfile.txt" set /p =,%%b<nul
        ) else (
            >> "newfile.txt" set /p =%%b<nul
            set comma=1
        )
    )
)
>> "newfile.txt" echo.


Report •

#2
June 2, 2010 at 23:08:13
Thanks for the quick response and answer, Judago. It works like a charm, wow! I am still a newbie in this. Instead of just taking the answer for granted, I would like to learn and understand how the code works, if you would explain it line by line? I have tried to search through the web for batch tutorial but all only give some simple examples here and there and I could not seem to piece them together.

Report •

#3
June 3, 2010 at 02:34:35
I didn't intend it to be, but it's a long one....


for /f "skip=2 tokens=1* delims=]" %%a in (' find /v /n "" "yourfile.txt" ') do (


Create a line iterating loop (for /f) that ignores the first two lines of input(skip=2), the reason for the skip is "find" adds a header line we don't want. The lines of text are then split on the character "]" (delims=]) and broken into two chunks, the first chunk and the rest of the line(tokens=1*), The first chunk will populate %%a and the rest of the line %%b.

The actual input for the loop is a command(marked either side with single quotes), all 'find /v /n "" "yourfile.txt" ' does is output all lines from the file prefixed with line numbers in the format of "[1]line of text". This is important because for /f always ignores blank lines, this way blank line will show up as "[x]" so the for loop won't ignore it.


    if "%%b"=="" (

Remember %%b is our "rest of line variable"? If %%b is blank it signals that a new record starts from the next line.


        >> "newfile.txt" echo.


This is one of the commands executed if %%b is empty, all this does is append a newline to the output text file.


        set comma=

This is the other command executed if %%b is empty, all it does is undefine the variable "comma" that is used as a flag to determine if I need to prefix a comma to the output or not.

    ) else (

This marks the end of the commands executed if %%b is empty and start the section executed if %%b does contain something.

        if defined comma (

This nested if statement checks if the variable "comma" is defined, this if statement must close before the else of the initial if statement. Take note that I used the defined keyword rather than expanding the variable, to expand the variable properly would require "SetLocal EnableDelayedExpansion" to be used, "defined" side steps this issue because all I needed was true/false.


            >> "newfile.txt" set /p =,%%b<nul

If comma is defined I want to prefix the text(%%b) with a comma and add it to the file. The trick here is using "set /p", although it's intended purpose is user input it is useful to output text without a newline, meaning it can append to the same line in the new file multiple times. The <nul is to make set /p exit immediately rather than waiting for the user.


        ) else (

This is the else on the "if defined comma" command, the condition for the following codeblock is that "comma" isn't defined(first record).


            >> "newfile.txt" set /p =%%b<nul


The condition is that "comma" isn't defined, so %%b is output without a comma.


            set comma=1

Again inside of the "defined" else clause, because I want to prefix a comma for the rest of the record I set comma to 1, it could be anything it just needs to be something.


        )

End of the "if defined" command.


    )

End of the 'if "%%b"=="" ' command.


)

End of the for loop.


>> "newfile.txt" echo.

Add a new line to the new file to make it ready to be appended to in future.


Caveats

Set /p - The first record can not begin with "=" because set /p doesn't allow the first character of "prompt string" to be "=". I don't know why, it just wont. The records prefixed with a comma are unaffected.

delims=] - For loops split on delimiters until the first non delimiter character, so if any lines start with "]" They will be stripped until the first character that isn't "]". They can be anywhere else on the line without any issues because * means the rest of the line including any delimiter characters.


http://judago.webs.com/forloopmadne...


Report •

Related Solutions

#4
June 4, 2010 at 22:11:38
Thank you so much, Judago!

Report •

Ask Question