 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Payam
Joined: 07 Apr 2004 Posts: 58
|
Posted: Wed Jun 30, 2004 10:08 am Post subject: Database functions ex: FileWriteLine |
|
|
FileWriteLine - be able to append to a specified line of a text file (maybe even with the option of at the beginning or end of the line)
FileDeleteLine - delete a specific line in a text file
These, primarily the former, would allow more flexibility in storing and changing data (in a text database for example).
As an example, lets say you have a comma delimited text file, you could then use ahk to modify a value in the middle of the file (instead of just being able to append to the bottom of the file).
Thanks Chris! |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Wed Jun 30, 2004 12:20 pm Post subject: |
|
|
These features will probably never be built-in because:
1) They are too rarely used (others are welcome to convince me otherwise).
2) They require the text file to be recreated (at least in the case of inserting, not necessarily deleting). Recreating a text file can be easily scripted, and with almost the same performance in a script as it would be if I were to build in the function. This is because disk IO is so much slower than the CPU overhead of the operation:
| Code: | ; Delete specified line from the file:
SetBatchLines, -1 ; Probably makes script as fast as any program for a disk intensive operation.
line_to_delete = 15
Loop, read, Text DB.txt, New Text DB.txt
{
if a_index <> %line_to_delete%
FileAppend, %A_LoopReadLine%`n
}
FileMove, New Text DB.txt, Text DB.txt, 1 |
Almost the exact same technique as above could be used to append some text to a line in the middle of the file:
| Code: | Loop, read, Text DB.txt, New Text DB.txt
{
if a_index <> %line_to_append_to%
FileAppend, %A_LoopReadLine%`n
else
FileAppend, %A_LoopReadLine%`,The text to append.`n
}
FileMove, New Text DB.txt, Text DB.txt, 1 |
Admittedly, there are ways to program the above operations so that an intermediate file is not needed (INI files probably do this). However, I do not think these methods help performance much, if at all. All they do is avoid the need to have temporarily double the amount of disk space available during the operation. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Wed Jun 30, 2004 2:11 pm Post subject: |
|
|
When using the above, be sure to have a backup of the file (at least during testing), because the script will overwrite the original with the new version. If something goes wrong during the process (e.g. disk full or bad sector), the entire file could be lost.
Also, I realized after posting that you do get a boost in performance when avoiding the temporary file. So would anyone else envision a realistic use for inserting/modifying/deleting specific lines in a text file?
I try to avoid adding commands that are used by only a tiny fraction of users, since they increase the size of the program and the memory it requires -- not to mention cluttering up the help file with something that potentially 99.99% of users would not find useful. |
|
| Back to top |
|
 |
beardboy
Joined: 02 Mar 2004 Posts: 444 Location: SLC, Utah
|
Posted: Wed Jun 30, 2004 4:11 pm Post subject: |
|
|
Chris,
I would use this feature, but I use a lot of text files as database type files for batch jobs, and I know that is rare.
thanks,
beardboy |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Wed Jun 30, 2004 6:50 pm Post subject: |
|
|
| But how often do you know the line number of the target line? Perhaps you would have an index file containing that info? Or perhaps it would be more appropriate to optionally delete a line based on a keyword that it contains? I guess the most versatile thing would be to have a subroutine that is called automatically for every line in the file. That subroutine could check the contents of the line and indicate whether it should be modified, deleted, or inserted-before. However, that's getting pretty complex and it seems that the examples I posted are actually simpler than this. |
|
| Back to top |
|
 |
beardboy
Joined: 02 Mar 2004 Posts: 444 Location: SLC, Utah
|
Posted: Wed Jun 30, 2004 9:06 pm Post subject: |
|
|
Chris,
I'm not saying that the feature should be added, just that I would most likely use it. I currently do a Loop and read the contents of the file and use FileAppend to re-write the file. Like the examples you gave.
thanks,
beardboy |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Wed Jun 30, 2004 10:20 pm Post subject: |
|
|
I should clarify: I'm asking for info about what parameters the command would take if it existed. It seems to me that in most cases you wouldn't know the line number of the target line beforehand. You'd have to have a file-reading loop just to determine this. Or alternatively, if not given the line number, what info would the command be given instead?
Also, how often is it that more than one line would need to be deleted/modified/inserted? If often, the loop technique currently used probably performs better than the command would (since the command must delete/modify/insert only one line at a time, and must rescan and rebuild the file each time). |
|
| Back to top |
|
 |
Payam
Joined: 07 Apr 2004 Posts: 58
|
Posted: Fri Jul 02, 2004 9:54 am Post subject: |
|
|
Chris, thank you - I can now more or less do what I need.
The main reason I thought this feature would be useful is for csv files for example.
Lets say for simplicity I have a db file of fruit names and their costs.
I wanted to lets say increase the price of oranges and apples by $1,etc or add a third paramter to it (like quantity available as the next field separated by a comma).
Nevertheless I can now accomplish it using the method you suggested. |
|
| Back to top |
|
 |
Guest
|
Posted: Fri Jul 09, 2004 4:35 am Post subject: |
|
|
I think these option are related to the ability to write scripts on the fly a expansion of this ability would be...
FileWriteStart ('various options')
Blah, Blah, Blah...
FileWriteEnd ('various options')
FileWriteto ('various options')
The user could then cut put down what he wanted and forward that 2 a file. Of course there would have to be something for carriage return and line. Or prehabs an options that assumes that for you.
FileWriteStart
#1 Blah, blah, blah, @CR
#2 Blah, blah, blah, @CR
FileWriteEnd |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Fri Jul 09, 2004 1:25 pm Post subject: |
|
|
Rajat suggested something similar and I think it would be useful. There's an item on the to-do list to support a line continuation character. By combining that with the technique of assigning to a variable first, the need to escape commas is avoided, though you would still have to escape percent signs:
| Code: | line =
_This is the first line.`n
_This is the second line, with literal comma.`n
FileAppend, %line%, %TargetFile% |
Does that seem like it would work okay? |
|
| Back to top |
|
 |
Guest
|
Posted: Sun Jul 11, 2004 11:31 am Post subject: |
|
|
| That would defintely improve the situation. |
|
| Back to top |
|
 |
daonlyfreez
Joined: 16 Mar 2005 Posts: 738 Location: Berlin
|
Posted: Tue Jul 12, 2005 3:42 pm Post subject: |
|
|
Here are some includeable functions that might be useful...
Important: I use the #-sign to differentiate between included functions/variables and the scripts own.
The includeable functions still use a temporary file, which overwrites the source file (based on the original snippets provided here by Chris).
Any errors resulting are therefore AT YOUR OWN RISK
file.ahk
| Code: | /* *** #File_Len ********************
Returns the number of lines in a file
Settings:
aFile = pathto\yourfile.txt
Example:
aFileLen := #File_Len(aFile)
msgbox, %aFileLen%
Original Source:
Chris (http://www.autohotkey.com)
*/
#File_Len(aFile)
{
#Main_SpeedMax()
Loop, Read, %aFile%
#File_Len = %A_Index%
#Main_SpeedRestore()
return #File_Len
}
/* *** #File_WriteLine ********************
Writes a string to a specific line in a file, with options
Settings:
aString = a text to insert
aFile = pathto\yourfile.txt
aLineNr = the line nr to insert into
theOption = choose from one of the following:
- r = replaces the whole existing line
- e = inserts the string at the end of the existing line
- s = inserts the string at the start of the existing line
- #(a number) = inserts the string at position # in the existing line
- d = delete the line, don't insert anything (FileDeleteLine)
Example:
aFile = C:\aPath\aFile.txt
#File_WriteLine("write this string to a file",aFile,14,"s")
Original Source:
Chris (http://www.autohotkey.com/forum/viewtopic.php?t=417)
*/
#File_WriteLine(aString,aFile,aLineNr,x)
{
#Main_SpeedMax()
Loop, read, %aFile%, %aFile%.tmp
{
if a_index <> %aLineNr%
FileAppend, %A_LoopReadLine%`n
else if x = r
FileAppend, %aString%`n
else if x = e
FileAppend, %A_LoopReadLine%%aString%`n
else if x = s
FileAppend, %aString%%A_LoopReadLine%`n
else if x is integer
{
aLineLen := StrLen(A_LoopReadLine)
remLineLen = %aLineLen%
remLineLen -= %aLineNr%
StringLeft, beforeString, A_LoopReadLine, %x%
StringMid, afterString, A_LoopReadLine, %aLineLen%, %remLineLen%, L
FileAppend, %beforeString%%aString%%afterString%`n
}
else if x = d
FileAppend,
else
#Main_Error("The option you provided is not valid",ERRORLEVEL,A_LineNumber,A_LineFile)
}
FileMove, %aFile%.tmp, %aFile%, 1
#Main_SpeedRestore()
} |
And here the used snippets from my main include file:
main.ahk
| Code: | #Main_SpeedMax()
{
global #prevBL
#prevBL = %A_BatchLines%
SetBatchLines = -1
}
#Main_SpeedRestore()
{
global #prevBL
SetBatchLines, %#prevBL%
}
#Main_Error(aMessage,aCaptEL,aLineNr,aScript)
{
MsgBox, 0, *** ERROR! ***, Message:`n`n%aMessage%`n`nErrorLevel: %aCaptEL%`n`nScript:`n`n%aScript%`n`nLine Nr: %aLineNr%
Pause, on
MsgBox, 1, Script Paused!, The script %aScript% was paused.`n`nPress 'OK' to continue or 'Cancel' to exit
IfMsgBox, OK, Pause, off
IfMsgBox, Cancel, Exit
} |
and finally a test script/snippet:
| Code: | #include C:\thepathtoyour\includefilesfolder\main.ahk
#include C:\thepathtoyour\includefilesfolder\file.ahk
; the following would insert the string "this is a test line to insert"
; into line number 11 at character position 10 in file %aFile%
aFile = %a_scriptdir%\aFile.txt
#File_WriteLine("this is a test line to insert",aFile,11,"10") |
'My' includeable-functions-library is still very much a work in progress, so any comments/improvement suggestions are welcome  _________________
Get your own Ron Paul 2008 userbar! |
|
| Back to top |
|
 |
Dragonscloud
Joined: 16 Jul 2005 Posts: 90
|
Posted: Tue Jul 26, 2005 7:55 pm Post subject: |
|
|
| Chris wrote: |
Also, how often is it that more than one line would need to be deleted/modified/inserted? If often, the loop technique currently used probably performs better than the command would (since the command must delete/modify/insert only one line at a time, and must rescan and rebuild the file each time). |
I think it'd be awesome to be able to replace multiple lines in a text document, script, cascading style sheet, or what-have-you. As a for-instance:
I have a huge CSS code in a web page. I want to be able to change a certain block of code on-the fly (scrollbar colors or what-have-you)
I could include a comment within the CSS like <!-- [ScrollBar] --> For whatever blocks of code I might want to change on-the-fly without having to hunt them down in the html editor. I'd like to be able to, in an ahk script, display in an edit field that block of code or do a gui-less replace between two commented lines such as
<!-- [ScrollBar] --> <!-- [/Scrollbar] -->
In other words, the script would look for beginning and ending "bookmarks" and act on the contents in between. Read loops, etc., could probably also work within the block. Rather than having to specify a line number, the script author would specify a beginning and ending string.
(Not syntactically correct, but should convey the gist:)
BlockReplace, BeginningString, EndingString [, ReplacementText, Options]
Loop, Read, %A_ReadBlockLine%, etc....
The above is probably possible already (I'm a novice), but simplification of the process would be welcome if practical. _________________ “yields falsehood when preceded by its quotation” yields falsehood when preceded by its quotation. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Wed Jul 27, 2005 3:36 am Post subject: |
|
|
Although some new file commands such as FileWrite and FileOpen will probably get added eventually, more elaborate actions such as searching and replacing text inside a file will probably not get built in. This is because the performance of having the script do it (either via FileRead or a file-reading loop) is approximately the same as having the program do it, at least when the file is uncached. The reason for this is that disk I/O is very slow compared to the CPU. Thus, the CPU spends most of its time waiting for the disk to serve up more data.
However, if you or anyone writes useful functions that would have relatively broad appeal, they would be candidates for distribution with AutoHotkey in a "standard includes" folder. This is almost as convenient as having new built-in commands because such functions could become visibible to a script via something like #Include <FileOps.ahk> |
|
| Back to top |
|
 |
Thalon
Joined: 12 Jul 2005 Posts: 640
|
Posted: Thu Dec 15, 2005 9:41 am Post subject: |
|
|
Hmm I didn't know that the complete file has to be recreated when you have to just insert a line (terrible ).
In this case I think a built-in-feature wouldn't be necessary...
My idea (in another thread) was like this:
I read a file to a variable and parse the variable for some content (because it performs much better then reading a file line by line).
Over the A_Index-Variable I would know the line-number I want to change (or insert something before). I hoped that inserting one line would perform also much better then rewriting my whole file (which can be 8+ MB in my case).
Hmm.. shit happens...
I will write a function to do this in AHK and provide it...
Thalon _________________ AHK-Icon-Changer
AHK-IRC
deutsches Forum
SacredVault |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|