Page 1 of 1 1
Topic Options
#152092 - 2005-11-23 03:56 PM Is this possible with Kixtart?
booey Offline
Getting the hang of it

Registered: 2005-07-25
Posts: 76
Loc: USA
Hi,

Is it possible to use Kixtart to look at a .csv file (or any text file) and copy lines 1-2000, 20001-4000, 4001-6000, etc... to a separate file for each range? In other words, lines 1-2000 will be in filename1.csv, 2001-4000 will be in filename2.csv, etc.

Any help is appreciated. Thanks.

Top
#152093 - 2005-11-23 04:17 PM Re: Is this possible with Kixtart?
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Yes. It's actually very easy.

Loop up Open(), ReadLine(), WriteLine() and Close() in the manual.

Post again if you have more questions.

Top
#152094 - 2005-11-23 04:22 PM Re: Is this possible with Kixtart?
Gargoyle Offline
MM club member
*****

Registered: 2004-03-09
Posts: 1597
Loc: Valley of the Sun (Arizona, US...
You can accomplish this READLINE() and a loop.

Code:

Dim $Line, $Counter
$Counter = 0
Open(1,"File.csv")
Open(2,"Range1.csv",5)
Open(3,"Range2.csv",5)
Open(4,"Range3.csv",5)
$Line = Readline(1)
While @Error = 0
Select
Case $Counter <= 2000
WriteLine(2, $Line + @CRLF)
$Counter = $Counter + 1
$Line = Readline(1)
Case $Counter => 20001 and $Counter <=4000
Writeline(3, $Line + @CRLF
$Counter = $Counter + 1
$Line = Readline(1)
Case $Counter >= 4001
WriteLine(4, $Line + @CRLF)
$Counter = $Counter + 1
$Line = Readline(1)
EndSelect
Loop
Close(1)
Close(2)
Close(3)
Close(4)

_________________________
Today is the tomorrow you worried about yesterday.

Top
#152095 - 2005-11-23 04:52 PM Re: Is this possible with Kixtart?
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
This is an example of a general purpose split UDF.

Just pass the UDF the source file name, target file name and how many lines you want in each file.

If you don't pass a target file name it will use the source file name. If you don't pass a number of lines it will assume 1000 lines.

The file sequence number is placed before the file suffix of the target file, or at the end of the file if it does not have a suffix.

Code:
Break ON
$=SetOption("Explicit","ON")

$=udfSplitFile("BIGFILE.TXT","SMALLFILE.TXT",1000)
If @ERROR "ERROR: ["+@ERROR+"] "+@SERROR+@CRLF EndIf

Exit 0

Function udfSplitFile($sSource,Optional $sTarget,Optional $iMaxLines)
Dim $sSuffix
Dim $iLinesLeft,$iFileSeq
Dim $fdSource,$fdTarget
Dim $sLine

If $sTarget="" $sTarget=$sSource EndIf
If CInt($iMaxLines=0) $iMaxLines=1000 EndIf
If InStrRev($sTarget,".")
$sSuffix=SubStr($sTarget,InStrRev($sTarget,"."))
$sTarget=Left($sTarget,InStrRev($sTarget,".")-1)
EndIf

$fdSource=FreeFileHandle()
If @ERROR $udfSplitFile=@ERROR Exit @ERROR EndIf

If Open($fdSource,$sSource) $udfSplitFile=@ERROR Exit @ERROR EndIf

$sLine=ReadLine($fdSource)
While Not @ERROR
If Not($iLinesLeft)
$iLinesLeft=CInt($iMaxLines)
If $fdTarget $fdTarget=Close($fdTarget) EndIf
$fdTarget=FreeFileHandle()
If @ERROR $udfSplitFile=@ERROR Exit @ERROR EndIf
$iFileSeq=$iFileSeq+1
If Exist($sTarget+$iFileSeq+$sSuffix)
Del $sTarget+$iFileSeq+$sSuffix
If @ERROR $udfSplitFile=@ERROR Exit @ERROR EndIf
EndIf
If Open($fdTarget,$sTarget+$iFileSeq+$sSuffix,1+4) $udfSplitFile=@ERROR Exit @ERROR EndIf
EndIf
$sLine=WriteLine($fdTarget,$sLine+@CRLF)
$iLinesLeft=$iLinesLeft-1
If @ERROR $udfSplitFile=@ERROR Exit @ERROR EndIf
$sLine=ReadLine($fdSource)
Loop

If $fdTarget $fdTarget=Close($fdTarget) EndIf
$fdSource=Close($fdSource)

EndFunction


Top
#152096 - 2005-11-23 05:09 PM Re: Is this possible with Kixtart?
DrillSergeant Offline
MM club member
*****

Registered: 2004-07-09
Posts: 1164
Loc: Eijsden, the Netherlands
Code:

$counter = 0

$nul = Open(1,"File.csv")

$Line = Readline(1)

While @ERROR = 0

$file = "Range" + val( int($counter/2000) + 1) + ".csv"

If $file<>$file_old
If $file_old<>""
$nul = Close(2)
EndIf
$nul = Open(2,$file,5)
EndIf

$nul = WriteLine(2, $Line + @CRLF)
$file_old = $file
$counter = $counter + 1

$Line = Readline(1)

Loop



Or something like this?
_________________________
The Code is out there

Top
#152097 - 2005-11-23 08:21 PM Re: Is this possible with Kixtart?
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
I'd actually use a combination of the techniques discussed here, using RedirectOutput() to eliminate the need to Open(), Write(), and Close() all the individual output files.
Code:
 
$SourceFile = 'file.csv'
$Counter = 1

Del 'c:\temp\subfile.????.csv' ; delete all output files


If $Open(5, $SourceFile, 2) ; open the source file
$Line = ReadLine(5) ; read a line
While Not @ERROR ; read until EndOfFile error

; create an index - 0000 to 9999 - to determine which group of 1000 we're in
$Index = Right('0000' + CStr(Int($Counter / 1000)), 4)

; Define the output file based on a base file name/path, the index, and the extension
$OutFile = 'c:\temp\subfile.' + $Index + '.csv'

; print the line, redirecting output to the current outfile
$ = RedirectOutput($OutFile)
$Line ?
$ = RedirectOutput('')

; Read the next line and increment the counter
$Line = ReadFile(5)
$Counter = $Counter + 1

Loop

$ = Close(5)

Else
? 'Error opening ' $SourceFile ' - Aborting!' ? ?
Exit 1
EndIf



Glenn

PS - this is an example - you'll want to add some error checking, and there's more efficient ways to handle the RedirectOutput. One thought - save the previous OutFile, and close/reopen the RedirectOutput only when it changes.
_________________________
Actually I am a Rocket Scientist! \:D

Top
#152098 - 2005-11-23 09:45 PM Re: Is this possible with Kixtart?
Bryce Offline
KiX Supporter
*****

Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
You could use the Tail() udf....
Code:

$file = tail("some large file.txt",-1)

$min = 2000
$max = 4000

if ubound($file) >= $min-1 and ubound($file) <= $max-1
? "printing all lines between " $min " and " $max " line numbers."
for $i = $min-1 to $max-1
? $file[$i]
next
endif
Code:


Bryce

Edited by Bryce (2005-11-23 09:47 PM)

Top
Page 1 of 1 1


Moderator:  Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 2220 anonymous users online.
Newest Members
Viginette, ManuvdWielNL, Sir_Barrington, batdk82, StuTheCoder
17888 Registered Users

Generated in 0.062 seconds in which 0.033 seconds were spent on a total of 12 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org