#152092 - 2005-11-23 03:56 PM
Is this possible with Kixtart?
|
booey
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
|
|
|
|
#152094 - 2005-11-23 04:22 PM
Re: Is this possible with Kixtart?
|
Gargoyle
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
   
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
|
|
|
|
#152097 - 2005-11-23 08:21 PM
Re: Is this possible with Kixtart?
|
Glenn Barnas
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!
|
|
Top
|
|
|
|
#152098 - 2005-11-23 09:45 PM
Re: Is this possible with Kixtart?
|
Bryce
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
|
|
|
|
Moderator: Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart
|
0 registered
and 2220 anonymous users online.
|
|
|