AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Library for Text file manipulation
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  

Should it be continued?
No, these are completely useless
4%
 4%  [ 1 ]
Yes, add more and more, make it big
96%
 96%  [ 24 ]
Total Votes : 25

Author Message
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Sun Jun 15, 2008 9:22 am    Post subject: Library for Text file manipulation Reply with quote

Hello community.
I couldn't found suitable functions to simplify typical text file manipulation.
Since text file manipulation is often used job and asked many times in forum.
I decided to make one to use later rather than making it everytime. hopefully neat one.
though i have only 6 functions for initial release. i'd like to add more functions later
suggestions and improvements are always welcome.

Edit : added '!' prefix for TextFile parameter which overwrite the file
without '!' prefix, it'll write to copy by default(eg: filename_copy.txt)
and now these functions will run under maximum batchline for performance


Download TXT.ahk to /Lib


Changes
    2008-06-18 : added AlignLeft(), AlignCenter(), AlignRight()
    2008-06-18 : HugoV contibuted Tail(), ReverseLines()
    2008-06-17 : added GetCSV(), SetCSV()
    2008-06-17 : HugoV contributed LineNumber(), Concat(), ColGet(), ColPut(), ColCut()
    2008-06-16 : added RegExReplace(), RemoveLines(), TrimLeft(), TrimRight()
    2008-06-15 : added TotalLines(), ReadLines(), RemoveDuplicateLines()


Contributors
Thanks for your efforts and contribution!
    HugoV Contributed LineNumber(), Concat(), ColGet(), ColPut(), ColCut(), Tail(), ReverseLines()


Common Parameters
    TextFile : The Filename including absolute path to read from and save to.
    ! Prefix : If TextFile starts with ! (eg: "!c:\sample.txt") will overwrite the text file else will save to copy of the text file (eg:Filename_copy.txt)
    Text : Text to Insert/Replace
    Line : Line to Insert/Replace (Lines counted from 1)
    StartLine : Start of Range
    EndLine : End of Range
    SearchText : Text to Replace
    ReplaceText : Text to be Replaced


Function List (Total of 25 functions)

*TextFile parameter in Red Color does not support ! prefix as does not needed

Basic Functions (Not writing the file, just return)
    TXT_TotalLines(TextFile) : Get total lines of text file
    TXT_ReadLines(TextFile, StartLine, EndLine) : Read range of lines from text file (Extended version of FileReadLine)
    TXT_Tail(TextFile, Lines=1) : Get tail(last line) of text file


Alignment Functions
    TXT_AlignLeft(TextFile, Columns=80) : Align Left the entire text file depend on total columns
    TXT_AlignCenter(TextFile, Columns=80) : Align Center the entire text file depend on total columns
    TXT_AlignRight(TextFile, Columns=80) : Align Right the entire text file depend on total columns
    TXT_ReverseLines(TextFile, StartLine = 0, EndLine = 0) : Realign range of lines with reverse order (0 to 0 = every lines by default)


Removement Functions
    TXT_RemoveLines(TextFile, StartLine, EndLine) : Remove range of lines in text file
    TXT_RemoveBlankLines(TextFile) : Simply removes all blank lines in text file
    TXT_RemoveDuplicateLines(TextFile, CaseSensitive="True") : Remove duplicated lines in text file, Case Sensitive by default


Replacement Functions
    TXT_Replace(TextFile, SearchText, ReplaceText="") : Replace Every %SearchText% to %ReplaceText% in text file
    TXT_RegExReplace(TextFile, StartLine, EndLine, NeedleRegEx, Replacement="") : Replace range of lines with Regular Expression
    TXT_ReplaceLine(TextFile, Line, Text="") : Simliar to InsertLine except it will replace the line instead of inserting


Insertion Functions
    TXT_LineNumber(TextFile, LeadingZeros = 0) : Insert Line Number on every line in text file with LeadingZero or not.
    TXT_InsertLine(TextFile, Line, Text) : Inserts specified %Text% at specified %Line%
    TXT_InsertPrefix(TextFile, StartLine, EndLine, Text) : Insert %Text% at beforehand on range of lines
    TXT_InsertSuffix(TextFile, StartLine, EndLine, Text) : Insert %Text% at afterward on range of lines


Column Functions
    TXT_ColGet(TextFile, StartColumn, EndColumn, Skip = 0) : Get texts between StartColumn and EndColumn. skip empty lines(0) or not
    TXT_ColPut(TextFile, StartColumn, Text, Skip = 0) : Put %Text% at specified %StartColumn%
    TXT_ColCut(TextFile, StartColumn, EndColumn) : Cut texts between %StartColumn% and %EndColumn%


Trimming Functions
    TXT_TrimLeft(TextFile, StartLine, EndLine, Count) : Trim left for range of lines (Work same as StringTrimLeft)
    TXT_TrimRight(TextFile, StartLine, EndLine, Count) : Trim right for range of lines (Work same as StringTrimRight)


CSV Functions
    TXT_GetCSV(TextFile, Row, Column, Delimiter=",") : Get field data from specific Row & Column. delimiter can be change to A_Space or A_Tab
    TXT_SetCSV(TextFile, Row, Column, Text="", Delimiter=",") : Set field data at specific Row & Column. delimiter can be change to A_Space or A_Tab

File Join/Split Functions
    TXT_ConCat(FirstTextFile, SecondTextFile, OutputFile, Blanks = 0, FirstPadMargin = 0, SecondPadMargin = 0) : Concatenate files, more explanation in source


Example
Code:
; Create sample file with 100000 lines
F=c:\sample.txt
FileDelete, %F%
Loop, 100000
    Var .= A_Index "`n"
FileAppend, %Var%, %F%

MsgBox % "Total lines of text file is : " TXT_Totallines(F)

; Performance benchmarking
DllCall("QueryPerformanceFrequency", "Int64 *", Freq)
DllCall("QueryPerformanceCounter", "Int64 *", Start)

;Insert prefix to range from 20 to 100
TXT_InsertPrefix("!" . F, 20, 30, "LineNumber : ")
;Insert suffix to range from 31 to 40
TXT_InsertSuffix("!" . F, 31, 40, "th line")
;Insert specified text to line 5
TXT_InsertLine("!" . F, 5, "This will be inserted at Line 5")
;Replace line 10 with specified text
TXT_ReplaceLine("!" . F, 10, "Line 10 will be replaced with this")
;Remove Lines of range from 41 to 1000
TXT_RemoveLines("!" . F, 41, 1000)
;Replace every 000 to 0
TXT_Replace("!" . F, 000, 0)

DllCall("QueryPerformanceCounter", "Int64 *", End)
MsgBox % "Elapsed Time is : " (End - Start)/Freq " Secs (6 Functions)"


Source
Code:
/*----------------------------------+
 Library for Text File Manipulation |
------------------------------------+ - heresy
Last Updated : 2008-06-18

-# Common Parameters -----------------------------------------------------------
TextFile :
    The Filename including path to read from and save to
    If TextFile starts with ! (eg: "!c:\sample.txt") will overwrite the text file
    else will save to copy of the text file (eg:Filename_copy.txt)

Text :
    Used with functinos which supports text insertion
   
Line :
    Used with functions which supports One-line process
   
StartLine :
    Used with functions which supports Range of lines
   
EndLine:
    Used with functions which supports Range of lines

SearchText :
    Used with functions which supports Replacement
   
ReplaceText :
    Used with functions which supports Replacement
--------------------------------------------------------------------------------

-# Functions -------------------------------------------------------------------
----------------+
Basic Functions |
----------------+
- TXT_TotalLines(TextFile)
    Get total lines of text file

- TXT_ReadLines(TextFile, StartLine, EndLine)
    Read range of lines from text file (Extended version of FileReadLine)

- TXT_Tail(TextFile, Lines = 1) by HugoV
    Get tail(last line) of text file

--------------------+
Alignment Functions |
--------------------+
- TXT_AlignLeft(TextFile, Columns=80)
- TXT_AlignCenter(TextFile, Columns=80)
- TXT_AlignRight(TextFile, Columns=80)
    Align texts Left/Center/Right based on total columns.
    Note that leading white spaces will be stripped out

- TXT_ReverseLines(TextFile, StartLine = 0, EndLine = 0) by HugoV
    Realign range of lines with reverse order
    Omit 2nd and 3rd parameters to affect on every lines

---------------------+
Removement Functions |
---------------------+
- TXT_RemoveLines(TextFile, StartLine, EndLine)
    Remove range of lines in text file
   
- TXT_RemoveBlankLines(TextFile)
    Simply removes all blank lines in text file

- TXT_RemoveDuplicateLines(TextFile, CaseSensitive="True")
    Remove duplicated lines in text file, Case Sensitive by default

----------------------+
Replacement Functions |
----------------------+
- TXT_Replace(TextFile, SearchText, ReplaceText="")
    Replace Every %SearchText% to %ReplaceText% in text file
    to replace with "", omit 3rd Parameter(ReplaceText)

- TXT_RegExReplace(TextFile, StartLine, EndLine, NeedleRegEx, Replacement="")
    Replace range of lines with Regular Expression
    to replace with "", omit Last parameter(Replacement)

- TXT_ReplaceLine(TextFile, Line, Text="")
    Simliar to InsertLine except it will replace the line instead of inserting
    to replace with "", omit 3rd Parameter(Text)

--------------------+
Insertion Functions |
--------------------+
- TXT_LineNumber(TextFile, LeadingZeros = 0) by HugoV
    Insert Line Number on every line in text file with LeadingZero or not.

- TXT_InsertLine(TextFile, Line, Text)
    Insert specified %Text% at specified %Line%

- TXT_InsertPrefix(TextFile, StartLine, EndLine, Text)
    Insert %Text% at beforehand on range of lines

- TXT_InsertSuffix(TextFile, StartLine, EndLine, Text)
    Insert %Text% at afterward on range of lines

-----------------+
Column Functions |
-----------------+
- TXT_ColGet(TextFile, StartColumn, EndColumn, Skip = 0) by HugoV
    Get texts between %StartColumn% and %EndColumn% and save.
    Empty lines can be ignored (Skip=0) or not
   
- TXT_ColPut(TextFile, StartColumn, Text, Skip = 0) by HugoV
    Put %Text% at specified %StartColumn% and save.
   
- TXT_ColCut(TextFile, StartColumn, EndColumn) by HugoV
    Cut texts between %StartColumn% and %EndColumn% and save.
   
-------------------+
Trimming Functions |
-------------------+
- TXT_TrimLeft(TextFile, StartLine, EndLine, Count)
  TXT_TrimRight(TextFile, StartLine, EndLine, Count)
    Trim left or right for range of lines (Work same as StringTrimLeft/Right)

--------------+
CSV Functions |
--------------+
- TXT_GetCSV(TextFile, Row, Column, Delimiter=",")
    Get field data from specific Row & Column
    also Delimiter can be changed. (eg: A_Space or A_Tab without ")

- TXT_SetCSV(TextFile, Row, Column, Text="", Delimiter=",")
    Set field data at specific Row & Column
    also Delimiter can be changed. (eg: A_Space or A_Tab without ")

--------------------------+
File Join/Split Functions |
--------------------------+
- TXT_ConCat(FirstTextFile, SecondTextFile, OutputFile, Blanks = 0, FirstPadMargin = 0, SecondPadMargin = 0) by HugoV
    Concatenate %FirstTextFile% and %SecondTextFile% and save to %OutputFile%
    Optionally can set specific blank, margin rules.
   
--------------------------------------------------------------------------------
*/

;Borrowed from SKAN. Thanks!
;http://www.autohotkey.com/forum/viewtopic.php?t=26146#162899
TXT_TotalLines(TextFile){
Original := A_BatchLines
SetBatchLines, -1
    FileRead, Str, %TextFile%
    StringReplace, Str, Str, `n, `n, UseErrorLevel
SetBatchLines, %Original%
    Return ErrorLevel+1
}

TXT_ReadLines(TextFile, StartLine, EndLine){
Original := A_BatchLines
SetBatchLines, -1
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index between %StartLine% and %Endline%
            OutPut .= A_LoopField "`n"
        Else if (A_Index=EndLine+1)
            Break
    }
SetBatchLines, %Original%
    Return OutPut
}

TXT_Replace(TextFile, SearchText, ReplaceText=""){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    StringReplace, Output, Str, %SearchText%, %ReplaceText%, All
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_RegExReplace(TextFile, StartLine, EndLine, NeedleRegEx, Replacement=""){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index between %StartLine% and %Endline%
        {
            OutPut .= RegExReplace(A_LoopField, NeedleRegEx, Replacement, Count)
            OutPut .= "`n"
            Counts += Count
        }
        Else
            OutPut .= A_LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
    Return Counts
}

TXT_RemoveLines(TextFile, StartLine, EndLine){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index between %StartLine% and %Endline%
            Continue
        Else
            OutPut .= A_LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_RemoveBlankLines(TextFile){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `r`n
        OutPut .= (RegExMatch(A_LoopField,"[\S]+?")) ? A_LoopField "`n" :
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_RemoveDuplicateLines(TextFile, CaseSensitive="True"){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Case := (CaseSensitive="True") ? "C" :
    Sort, Str, U %Case%
    Removed := Errorlevel
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
    Return Removed
}

TXT_InsertLine(TextFile, Line, Text){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index < %Line%
            Head .= A_LoopField "`n"
        Else If A_Index >= %Line%
            Tail .= A_LoopField "`n"
    }
    OutPut := Head . Text "`n" . Tail
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_ReplaceLine(TextFile, Line, ReplaceText=""){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
        OutPut .= (A_Index=Line) ? ReplaceText "`n" : A_LoopField "`n"
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_InsertPrefix(TextFile, StartLine, EndLine, Text){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index between %StartLine% and %Endline%
            OutPut .= Text A_LoopField "`n"
        Else
            OutPut .= A_LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_InsertSuffix(TextFile, StartLine, EndLine, Text){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index between %StartLine% and %Endline%
            OutPut .= A_LoopField Text "`n"
        Else
            OutPut .= A_LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_TrimLeft(TextFile, StartLine, EndLine, Count){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index between %StartLine% and %Endline%
        {
            StringTrimLeft, StrOutPut, A_LoopField, %Count%
            OutPut .= StrOutPut "`n"
        }
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_TrimRight(TextFile, StartLine, EndLine, Count){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If A_Index between %StartLine% and %Endline%
        {
            StringTrimRight, StrOutPut, A_LoopField, %Count%
            OutPut .= StrOutPut "`n"
        }
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_AlignLeft(TextFile, Columns=80){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        LoopField := RegExReplace(A_LoopField,"(^\s+)")
        SpaceNum := Columns-StrLen(LoopField)-1
        OutPut .= LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_AlignCenter(TextFile, Columns=80){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        LoopField := RegExReplace(A_LoopField,"^\s+")
        SpaceNum := (Columns-StrLen(LoopField)-1)/2
        VarSetCapacity(Spaces%A_Index%, SpaceNum, 32)
        If (StrLen(LoopField) >= Columns)
            OutPut .= LoopFIeld "`n"
        Else
            OutPut .= Spaces%A_Index% LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_AlignRight(TextFile, Columns=80){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        LoopField := RegExReplace(A_LoopField,"^\s+")
        SpaceNum := Columns-StrLen(LoopField)-1
        VarSetCapacity(Spaces%A_Index%, SpaceNum, 32)
        If (StrLen(LoopField) >= Columns)
            OutPut .= LoopFIeld "`n"
        Else
            OutPut .= Spaces%A_Index% LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_GetCSV(TextFile, Row=1, Column=1, Delimiter=","){ ;A_Tab, A_Space
Original := A_BatchLines
SetBatchLines, -1
    FileReadLine, Str, %TextFile%, %Row%
    StringSplit, Line, Str, %Delimiter%
    Output := Line%Column%
SetBatchLines, %Original%
    Return Output
}

; How SetCSV Works :
; 1) Get all lines into memory
; 2) If processing line doesn't match to specified Row, Don't touch it
; 3) Else Split row by delimiter
; 4) If A_Index matches to specified column set it with specified text
; 5) add delimiter or not based on column position (last=don't add)
TXT_SetCSV(TextFile, Row, Column, Text="", Delimiter=","){ ;A_Tab, A_Space
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If (A_Index!=Row)
            OutPut .= A_LoopField "`n"   
        Else
        {
            StringSplit, Line, A_LoopField, %Delimiter%
            Loop, %Line0%
            {
                if (A_Index!=Column)
                    Output .= Line%A_Index% Delimiter
                Else
                    OutPut .= (Line0!=Column) ? Text Delimiter : Text
            }
            OutPut .= "`n"
        }
    }
    If OW {
        FileDelete, %TextFile%
        If ErrorLevel
            Return ErrorLevel
        FileAppend, %OutPut%, %TextFile%
        If ErrorLevel
            Return ErrorLevel
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        If ErrorLevel
            Return ErrorLevel
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
        If ErrorLevel
            Return ErrorLevel       
    }
SetBatchLines, %Original%
}



; __________________________________________________________
/*                                                         /
    Functions below this are contributed by other people. /
    Thanks for their efforts and contribution !          /
  ______________________________________________________/
*/



;____________________
; Functions by HugoV \________________________________________________
; http://www.autohotkey.com/forum/profile.php?mode=viewprofile&u=5470 |
;____________________________________________________________________/

/*
Based on:
CONCATenate text files, ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip

Usage: TXT_ConCat(FirstTextFile, SecondTextFile, OutputFile, Blanks = 0, FirstPadMargin = 0, SecondPadMargin = 0)

With TXT_ConCat you can join Text files side by side.
Blanks is number of blanks between lines
You can pad with blanks the right margin of either of the text files,
for this use FirstPadMargin and SecondPadMargin
Example: TXT_ConCat("file1.txt","file2.txt","concat.txt","15","5","7")
-> 15 spaces between the lines from file1 and file1, padding first file 5 spaces, padding Send file 7

Improvement: perhaps introduce a character which can be used instead of the spaces

*/       
TXT_ConCat(FirstTextFile, SecondTextFile, OutputFile, Blanks = 0, FirstPadMargin = 0, SecondPadMargin = 0){
Original := A_BatchLines
SetBatchLines, -1
    If (Blanks > 0)
        Loop, %Blanks%
        InsertBlanks .= A_Space
    If (FirstPadMargin > 0)
        Loop, %FirstPadMargin%
        PaddingFile1 .= A_Space
    If (SecondPadMargin > 0)
        Loop, %SecondPadMargin%
        PaddingFile2 .= A_Space
; first we need to determin the file with the most lines for our loop
    File1:=TXT_TotalLines(FirstTextFile)
    File2:=TXT_TotalLines(SecondTextFile)
    If (File1 > File2)
        MaxLoop:=File1
    Else
        MaxLoop:=File2
    Loop, %MaxLoop%
    {
    FileReadLine, Section1, %FirstTextFile%, %A_Index%
    FileReadLine, Section2, %SecondTextFile%, %A_Index%
    OutPut .=  Section1 PaddingFile1 InsertBlanks Section2 PaddingFile2 "`n"
    Section1= ; otherwise it will remember the last line from the shortest file
    Section2=
    }
    FileAppend, %OutPut%, %OutputFile% 
SetBatchLines, %Original%
}

/*
Usage: TXT_LineNumber(TextFile, LeadingZeros = 0)
LeadingZeros = 0 No padding with leading zeros
LeadingZeros >= 1 Include padding with leading zeros (001 v 1)
*/
TXT_LineNumber(TextFile, LeadingZeros = 0){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    If (LeadingZeros > 0)
    {
        StringReplace, Str, Str, `n, `n, UseErrorLevel
        Lines:=ErrorLevel+1
        Padding:=StrLen(Lines)
        Loop, %Padding%
            PadLines .= "0"
    }
    Loop, Parse, Str, `n
    {
        LineNumber:= A_Index
        If (LeadingZeros > 0)
        {
            LineNumber := Padlines LineNumber  ; add padding
            StringRight, LineNumber, LineNumber, StrLen(Lines) ; remove excess padding
        }
    OutPut .= LineNumber A_Space A_LoopField "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_ColGet(TextFile, StartColumn, EndColumn, Skip = 0){ ;skip = empty lines
Original := A_BatchLines
SetBatchLines, -1
TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    EndColumn:=(EndColumn+1)-StartColumn
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        If (Skip = 1) and (A_LoopField ="")
            Continue
        StringMid, Section, A_LoopField, StartColumn,EndColumn
        OutPut .= Section "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
    FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

/*
Based on:
COLPUT.EXE & CUT.EXE, ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip
*/

TXT_ColPut(TextFile, StartColumn, Text, Skip = 0){ ; skip = shorter lines (e.g. lines shorter startcolumn position)
Original := A_BatchLines
SetBatchLines, -1
StartColumn--
    FileRead, Str, %TextFile%
TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    Loop, Parse, Str, `n, `r
    {
   StringLeft, Section1, A_LoopField, StartColumn
        StringMid, Section2, A_LoopField, StartColumn
        If (Skip = 1) and (StrLen(A_LoopField) < StartColumn)
                     OutPut .= Section1 Section2 "`n"
            Else       
                     OutPut .= Section1 Text Section2 "`n"

    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
   FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_ColCut(TextFile, StartColumn, EndColumn){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    StartColumn--
    EndColumn++
    FileRead, Str, %TextFile%
    Loop, Parse, Str, `n, `r
    {
        StringLeft, Section1, A_LoopField, StartColumn
        StringMid, Section2, A_LoopField, EndColumn
        OutPut .= Section1 Section2 "`n"
    }
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
        FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

TXT_Tail(TextFile, Lines = 1) ;have dependency on TotalLines / ReadLines
{
Original := A_BatchLines
SetBatchLines, -1
    Lines--
    Endline:=TXT_TotalLines(TextFile)
    StartLine:=EndLine - Lines
    OutPut:=TXT_ReadLines(TextFile, Startline, EndLine)
SetBatchLines, %Original%
    Return Output
}

TXT_ReverseLines(TextFile, StartLine = 0, EndLine = 0){
Original := A_BatchLines
SetBatchLines, -1
    TextFile := (SubStr(TextFile,1,1)="!") ? (SubStr(TextFile,2),OW=1) : TextFile
    FileRead, Str, %TextFile%
    StringSplit, Line, Str, `n, `r
    If (EndLine = 0)
        EndLine:=Line0
    If (EndLine > Line0)
        EndLine:=Line0
    If (StartLine > 0) ; get first section
    {
        Loop, Parse, Str, `n, `r
        {
        If (A_Index < StartLine)
            Output1 .= A_LoopField "`n"
        Else
            Break
        }
    }
    CountDown:=EndLine+1
    Loop, Parse, Str, `n, `r ; get reversed section
    {
        If A_Index between %StartLine% and %Endline%
        {
        CountDown--
        Output2 .= Line%CountDown% "`n"
        }
        If A_Index > Endline
            Break
    }
    If (EndLine < Line0) ; get last section
    {
        Loop, Parse, Str, `n, `r
        {
        If (A_Index > EndLine)
            Output3 .= A_LoopField "`n"
        }
    }
    OutPut.= Output1 Output2 Output3
    StringTrimRight, OutPut, OutPut, 1 ; remove trailing `n
    If OW {
        FileDelete, %TextFile%
        FileAppend, %OutPut%, %TextFile%
    }
    Else {
        SplitPath, TextFile,, Dir, Ext, Name
        FileDelete, % Dir "\" Name "_copy." Ext
    FileAppend, %OutPut%, % Dir "\" Name "_copy." Ext
    }
SetBatchLines, %Original%
}

_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com


Last edited by heresy on Wed Jun 18, 2008 4:08 pm; edited 12 times in total
Back to top
View user's profile Send private message
Krogdor



Joined: 18 Apr 2008
Posts: 1020
Location: The Interwebs

PostPosted: Sun Jun 15, 2008 9:32 am    Post subject: Reply with quote

Great, I've been wondering about the best way to go about this! Looks wonderful.

Thanks Very Happy
Back to top
View user's profile Send private message AIM Address
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Mon Jun 16, 2008 11:20 am    Post subject: Reply with quote

Krogdor wrote:
I've been wondering about the best way
Thanks krogdor, i hope i'm doing the best way ! Smile
_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com
Back to top
View user's profile Send private message
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Tue Jun 17, 2008 6:05 pm    Post subject: Reply with quote

Just updated the library.
Now it has 20 functions in total.
HugoV contributed many functions today. which are most wanted functions.
These functions are huge improvements for the library.
with HugoV's functions, you can handle text files with column based.

Big Thanks to HugoV for his great contribution !
_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com
Back to top
View user's profile Send private message
Rhys



Joined: 17 Apr 2007
Posts: 730
Location: Florida

PostPosted: Wed Jun 18, 2008 4:18 pm    Post subject: Reply with quote

Looks promising!
_________________
[Join IRC!]
Back to top
View user's profile Send private message
HugoV



Joined: 27 May 2007
Posts: 532

PostPosted: Wed Jun 18, 2008 7:52 pm    Post subject: Reply with quote

@Rhys: I think so too, but perhaps I'm slightly biased Wink
and I suspect there will be a couple of more functions added to this
lib. Cool

Given your interest in CSV related matters (I've seen you help out
others in the Help forum) you might have some thoughts (functions
even) for CSV files Question
Back to top
View user's profile Send private message
neXt



Joined: 19 Mar 2007
Posts: 463

PostPosted: Thu Jun 19, 2008 4:19 am    Post subject: Reply with quote

Your library will definitely be something VERY useful! Please, add CSV functions to it!!!
Back to top
View user's profile Send private message
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Fri Jun 20, 2008 3:03 pm    Post subject: Reply with quote

Thanks for your feedbacks.

i'll make it grow gradually. CSV related functions as well.
suggestions / improvements / contributions are still needed.
anyone interest? Smile
_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com
Back to top
View user's profile Send private message
neXt



Joined: 19 Mar 2007
Posts: 463

PostPosted: Fri Jun 20, 2008 5:08 pm    Post subject: Reply with quote

Yeah, save the file in memory with a trigger function, and then work with file contents in memory until changes need to be finalized.
Here is what i started for my CSV library:
Code:
set_CSV(__file, __delimiter=",") {
   global

   SplitPath __file, __name
   _row = 0
   _col = 0
   fileRead _file, %__file%
   
   loop parse, _file, `n
   {
      _row++
      loop parse, A_LoopField, %__delimiter%
      {
         if(_row = 1)
            _col++

         __matrix%_row%_%A_Index% = %A_LoopField%
      }
   }
return
}


CSV_totalRows() {
   global
   return % --_row    ;%
}
CSV_totalColumns() {
   global
   return % _col        ;%
}

CSV_readCell(row = 1, column = 1) {
   global
   return % __matrix%row%_%column%           ;%
}

CSV_writeCell(row, column, value) {
   global
   __matrix%row%_%column% := value
   
   return % __matrix%row%_%column%           ;%
}

Here is how it works: set_CSV() reads a file into 2 dimensional array, since all vars are declared as global the rest of my lib functions can use that array. Example:

Code:
set_CSV("file.csv")

MsgBox % CSV_totalRows()          ;%
MsgBox % CSV_readCell(5, 2)          ;%


I'm not sure if this is the best way to do it, but it's the only thing that i was able to this of.
[/code]
Back to top
View user's profile Send private message
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Fri Jun 20, 2008 6:42 pm    Post subject: Reply with quote

Thanks for your interest neXt.
actually this library isn't ideal for massive file operations regarding to the structure
basically this library was made for beginners who can't write these things by themselves.
so i tried to simplify all the processes for them.
if we add trigger feature for Var/File it will also cause increasing the complexity of usage. (for beginners)
adding Trigger issue is need to be considered more unless we're going to split this library for other purpose

and also, me and HugoV are working on CSV functions to obey to RFC4180 or not.
after this problem is solved. i'll look into your functions soon.
Thanks !
_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com
Back to top
View user's profile Send private message
infogulch



Joined: 27 Mar 2008
Posts: 150
Location: USA

PostPosted: Fri Jun 27, 2008 11:23 pm    Post subject: Reply with quote

How about a tab replacing func?
Here's a simple leading tab replacement func:
Code:
;returns str with leading tabs replaced with tablen # of spaces
TXT_ReplaceLeadingTabs(str, tablen=4) {
   loop, %tablen%
      tabrep .= " "
   loop {    ;it only replaces one level of tabs at a time, so loop to get them all
      str := RegExReplace( str, "m)^([ ]{0,})\t", "$1" . tabrep, lRep )
      if !lRep
         break
   }
   return str
}
What would be really cool is a tab replacement function that replaces tabs in the middle of a line with the correct number of spaces to reach the next tabstop, tho that would be rather difficult. Razz (actually, i have an idea.. Shocked Very Happy )

Also a spaces to tab replacement would be nice.
Would you like a func that replaces tabs in the middle of a line?
_________________
Back to top
View user's profile Send private message
tcgbp



Joined: 04 Apr 2008
Posts: 24
Location: China

PostPosted: Sat Jun 28, 2008 5:42 am    Post subject: Reply with quote

I hope it will support the .ahk file also and that won't be hard to achieve
Back to top
View user's profile Send private message
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Sat Jun 28, 2008 6:34 am    Post subject: Reply with quote

tcgbp wrote:
I hope it will support the .ahk file also and that won't be hard to achieve

since .ahk files are plain text it's already compatible. .html .ini or any other plain text files as well
_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com
Back to top
View user's profile Send private message
Originalsim



Joined: 08 Aug 2008
Posts: 9

PostPosted: Fri Aug 08, 2008 5:51 pm    Post subject: Reply with quote

Could someone please point me to what I am missing.
I load this library up correctly and then make an .ahk with the following contents.
Code:

TXT_TotalLines(Textfile)


Where is my textfile name supposed to go?
I am trying to get the lines for "c:\appdata.txt"
Regardless of where and how I type my file name in the above code all I get is the either of these 2 errors.

"error at line 1. The following variable name contains an illegal character "appdata.txt" the program will exit"
Or
"... error. the leftmost character above is illegal in an expression..."

I have made plenty of macros but now that I am trying to delve deeper I am just missing it.
Any help would be greatly appreciated.
Thanks.
Back to top
View user's profile Send private message
Guest






PostPosted: Fri Aug 08, 2008 7:10 pm    Post subject: Reply with quote

Originalsim wrote:
Where is my textfile name supposed to go?
I am trying to get the lines for "c:\appdata.txt"
Code:
MsgBox % TXT_TotalLines("c:\appdata.txt")
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group