Page 1 of 1

batch file to read imput file, create seperate files

Posted: 20 Jul 2010 15:15
by gheimstead
Well, I thought I was better at this than I am and I've got a problem I need some help with. I thought this would be simple, but at least right now, apparently I'm brain dead...

Here's the problem... I have a file called import.txt, the file layout looks like this...

4323
Name of Company
Light
no
no
no
no
no
no

4325
Name of next company
#N/A
no
no
no
no
no
no

Each record is exactly the same size, seperated by a space. Here's what I would like the batch file to do...

read import.txt
Create a file from the first line of each record, i.e., 4323.txt
insert the next eight lines exactly as shown
move the the next record and do it all again until all the records are seperate files.

Thanks in advance for any help, I really appreciate it!
Gary

Re: batch file to read imput file, create seperate files

Posted: 20 Jul 2010 16:18
by aGerman
It's not that easy. Maybe it will fail if the number of lines is greater than the 32bit limit for numeric expressions in batch.

Code: Select all

@echo off &setlocal
set "empty=0"
for /f "delims=: tokens=1*" %%a in ('findstr /n "^" "import.txt"') do (
  if "%%b"=="" (
    call set "empty=%%empty%% %%a"
  ) else (
    set "line_%%a=%%b"
  )
)

for %%a in (%empty%) do (
  set /a nameLine=%%a+1
  set /a startLine=%%a+2
  set /a endLine=%%a+9
  call :proc
)
goto :eof

:proc
call set "name=%%line_%nameLine%%%.txt
if "%name%"==".txt" goto :eof
>"%name%" type nul
for /l %%a in (%startLine%,1,%endLine%) do (
 >>"%name%" call echo.%%line_%%a%%
)
goto :eof



This code should work if the separator is an empty line.
But you wrote the separator is a space. If this is realy true you have to replace:

Code: Select all

  if "%%b"==" " (


Regards
aGerman

Re: batch file to read imput file, create seperate files

Posted: 20 Jul 2010 17:31
by gheimstead
Right on the money, I did have to add the space though. Can't thank you enough. I found the errors I was making, so I learned a lot, which always makes things better in the long run...

Thanks again, I really appreciate you time and effort!
Gary

Re: batch file to read imput file, create seperate files

Posted: 21 Jul 2010 19:50
by ghostmachine4
@OP, what if next time you have more than 8 lines?

Re: batch file to read imput file, create seperate files

Posted: 22 Jul 2010 10:59
by gheimstead
set /a endLine=%%a+9 <--- should just have to change this value...

Re: batch file to read imput file, create seperate files

Posted: 22 Jul 2010 12:06
by aGerman
Exactly. :wink:

Re: batch file to read imput file, create seperate files

Posted: 22 Jul 2010 20:21
by ghostmachine4
gheimstead wrote:set /a endLine=%%a+9 <--- should just have to change this value...

what if you don't know this value in advance ? that's the question i am asking.

Re: batch file to read imput file, create seperate files

Posted: 22 Jul 2010 20:47
by aGerman
Into variable %empty% you can find all "separator lines" (space separated). It's easy to calculate the difference between two values to get the number of lines in a block.
But remember:
Each record is exactly the same size, seperated by a space...

That was one of the preconditions.

Regards
aGerman

Re: batch file to read imput file, create seperate files

Posted: 22 Jul 2010 21:19
by ghostmachine4
aGerman wrote:Into variable %empty% you can find all "separator lines" (space separated). It's easy to calculate the difference between two values to get the number of lines in a block.
But remember:
Each record is exactly the same size, seperated by a space...

That was one of the preconditions.

Regards
aGerman


By "each record", do you mean something like the below is one record?

Code: Select all

4323
Name of Company
Light
no
no
no
no
no
no
     <----- space here or newline until the next "block"


For me, i simply call it a block. And a record is simply a row of text. ie 4323 is one record, Name of Company is another record.
My question is, what if the number of records following "4323" is not fixed at any one time. Sometimes it may be 8 lines until the next "block".
sometimes it may be 11 lines... ie Same size at any one time ?

You mentioned that its easy to calculate the difference, so can you show it in your batch for completeness? Although OP did not ask for it, but I think its important so that the batch won't break in future when the number of records differ.

Re: batch file to read imput file, create seperate files

Posted: 23 Jul 2010 07:10
by aGerman
ghostmachine4 wrote:By "each record", do you mean something like the below is one record?

Yes. But the OP called it "record". I would also call it "block".


ghostmachine4 wrote:You mentioned that its easy to calculate the difference, so can you show it in your batch for completeness? Although OP did not ask for it, but I think its important so that the batch won't break in future when the number of records differ.

If the OP says that each block has the same size then I have to believe it.
But, of course I can show you the code for blocks with a different size.

import.txt

Code: Select all

4323
Name of Company
Light
4
5
 
4324
Name of Company
Light
4
5
6
7
8
9
10
11
 
4325
Name of next company
#N/A
4
5
6
7
8
9

You have to add the spaces by hand. It's not shown on the website.


batch code

Code: Select all

@echo off &setlocal
set "empty=0"
for /f "delims=: tokens=1*" %%a in ('findstr /n "^" "import.txt"') do (
  set "n=%%a"
  if "%%b"==" " (
    call set "empty=%%empty%% %%a"
  ) else (
    set "line_%%a=%%b"
  )
)
set /a n+=1
set "empty=%empty% %n%"

for %%a in (%empty%) do (
  if %%a==0 (
    set "before=%%a"
  ) else (
    call set /a dif=%%a-%%before%%
    call set /a nameLine=%%before%%+1
    call set /a startLine=%%before%%+2
    call set /a endLine=%%before%%+%%dif%%-1
    set "before=%%a"
    call :proc
  )
)
goto :eof

:proc
call set "name=%%line_%nameLine%%%.txt
if "%name%"==".txt" goto :eof
>"%name%" type nul
for /l %%a in (%startLine%,1,%endLine%) do (
  >>"%name%" call echo.%%line_%%a%%
)
goto :eof


As you can see it's really easy. You need just one further information: the line number after the last line to append it to %empty%. But this is simple as well.

Regards
aGerman

Re: batch file to read imput file, create seperate files

Posted: 23 Jul 2010 08:58
by ghostmachine4
I am running your code against your sample import.txt. Only 4323.txt is produced.

Code: Select all

C:\test>dir 43*txt
 Volume in drive C has no label.
 Volume Serial Number is 08AC-4F03

 Directory of C:\test

File Not Found

C:\test>more import.txt
4323
Name of Company
Light
4
5

4324
Name of Company
Light
4
5
6
7
8
9
10
11

4325
Name of next company
#N/A
4
5
6
7
8
9

C:\test>test.bat

C:\test>dir 43*txt
 Volume in drive C has no label.
 Volume Serial Number is 08AC-4F03

 Directory of C:\test

07/23/2010  10:57 PM               142   4323.txt
               1 File(s)            142 bytes
               0 Dir(s)   3,541,655,552 bytes free

C:\test>more 4323.txt
Name of Company
Light
4
5

4324
Name of Company
Light
4
5
6
7
8
9
10
11

4325
Name of next company
#N/A
4
5
6
7
8
9


A look at the file 4323.txt shows that the other blocks are inside it, which is wrong. Can you show where it went wrong ? Does it have anything
to do with having to add empty spaces manually ?

Now ,see my gawk one liner below

Code: Select all

C:\test>del 4323.txt

C:\test>gawk -vRS= -vFS="\n" "{print $0 > $1\".txt\"}" import.txt

C:\test>dir 43*txt
 Volume in drive C has no label.
 Volume Serial Number is 08AC-4F03

 Directory of C:\test

07/23/2010  11:00 PM                36 4323.txt
07/23/2010  11:00 PM                56 4324.txt
07/23/2010  11:00 PM                52 4325.txt
               3 File(s)            144 bytes
               0 Dir(s)   3,541,655,552 bytes free

C:\test>more 4323.txt
4323
Name of Company
Light
4
5

C:\test>more 4324.txt
4324
Name of Company
Light
4
5
6
7
8
9
10
11

C:\test>more 4325.txt
4325
Name of next company
#N/A
4
5
6
7
8
9

Re: batch file to read imput file, create seperate files

Posted: 23 Jul 2010 09:19
by aGerman
ghostmachine4 wrote:Can you show where it went wrong ? Does it have anything to do with having to add empty spaces manually ?

Yes. Have a look at the OP's posts. The "empty" lines are not empty. There is placed one single space. But the forum software does remove it, that's why I wrote that you have to add it manually in your text file.


ghostmachine4 wrote:Now ,see my gawk one liner below

Of course, sometimes it's much easier to use an additional tool or a different language.
But I try to solve the problems using native batch. The reason why is that you can use it on each Windows OS without additional software.

Regards
aGerman

Re: batch file to read imput file, create seperate files

Posted: 23 Jul 2010 09:38
by ghostmachine4
aGerman wrote:
ghostmachine4 wrote:The reason why is that you can use it on each Windows OS without additional software.

the problem is, commands present in one version of windows may not be present on another. eg choice.exe. You have to download from somewhere as well. Things like tasklist is not present as well in NT. (correct me if i am wrong) and many others. True, batch is native, but there are many cons than pros that makes it not a user friendly tool to use. Things that can be done easily needs to be worked around due to its limitations , making code development slow and unproductive. Not to mention the number of LOC sometimes makes the batch file not easy to maintain.
If i want to choose a native language, i would go for vbscript instead.

Re: batch file to read imput file, create seperate files

Posted: 23 Jul 2010 10:18
by aGerman
The topic of this forum is:
Discussion forum for all WinXP batch related topics.

That means we're talking about cmd.exe and not about command.com.
And if there are more commands available on Vista or Win7, so what, nice to have ...
BTW Have a look at the commands I used ...

On the other hand: Feel free to use each tool you want. It's not forbidden :wink:

Regards
aGerman