AutoHotkey Community

It is currently May 26th, 2012, 3:21 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: FileDeleteLine()
PostPosted: November 9th, 2007, 4:38 am 
Offline

Joined: July 15th, 2007, 1:43 am
Posts: 1320
I have yet to see one of these functions on the forums Other then the post Chris made way back in '04 Here so I decided to make one my self:

Code:
FileDeleteLine(FileName, LineNum)
{
   FileReadLine, Line_Contents, %FileName%, LineNum
   FileRead, File_Contents, %FileName%
   StringReplace, New_File, File_Contents, %Line_Contents%
   FileDelete, %FileName%
   FileAppend, %New_File%, %FileName%
   }


Example:

Code:
FileDeleteLine("TestFile.txt", 2)


If there is a shorter way of doing this, please. Share.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 7:23 pm 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8666
Location: Salem, MA
there is a bug - for example
Code:
filedelete, temp.txt
fileappend,
(
1
2
2
2
1
3
), temp.txt


FileDeleteLine("temp.txt",5)
FileRead, OutputVar, temp.txt
msgbox, %OutputVar%

FileDeleteLine(FileName, LineNum)
{
   FileReadLine, Line_Contents, %FileName%, LineNum
   FileRead, File_Contents, %FileName%
   StringReplace, New_File, File_Contents, %Line_Contents%
   StringReplace, New_File, New_File, `n ; Credits to en for showing me how to do this a while back. It has still helped me quite alot.
   FileDelete, %FileName%
   FileAppend, %New_File%, %FileName%
}

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 7:29 pm 
Offline

Joined: July 15th, 2007, 1:43 am
Posts: 1320
Just use the newest code posted. (Take out the StringReplace `n)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 7:39 pm 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8666
Location: Salem, MA
that is actually worse.

the problem I am trying to point out is that the cose wants to delete the 5th line, but actually deletes the first line, because they contain the same text.

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 7:47 pm 
Offline

Joined: July 15th, 2007, 1:43 am
Posts: 1320
Any suggestions?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 7:50 pm 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8666
Location: Salem, MA
make a file reading loop, and in the loop, check for A_Index matching the line they want to delete, and skip it (continue).

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 8:12 pm 
Offline

Joined: July 15th, 2007, 1:43 am
Posts: 1320
Code I'm using:

Code:
FileDeleteLine("TestFile.txt", 3)

FileDeleteLine(FileName, LineNum)
{
   FileReadLine, Line_Contents, %FileName%, LineNum
   FileRead, File_Contents, %FileName%
   Loop, Parse, File_Contents, `n
   {
      If A_Index != %LineNum%
      {
         MsgBox,, Not Found, Line was not found!
         }
      If A_Index = %LineNum%
      {
         MsgBox,, Found, Line was found!
         }
      }
   FileDelete, %FileName%
   FileAppend, %New_File%, %FileName%
   }


Still deletes the first line it finds with the contents of the selected line. And yet, it does recognize the line.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 8:15 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5347
Location: UK
Here's my version, it uses only one file read for performance:

Code:
FileDeleteLine(file, line = 1, eol = "`n") {
   ; eol = end of line character
   FileRead, src, %file%
   If line = 1 ; offset should be 0 for first line:
      start = 0
   Else {
      line-- ; since there is no linefeed at the start (i.e. 0 based index)
      StringGetPos, start, src, %eol%, L%line% ; find position of specified line
      If ErrorLevel != 0 ; if it was not found, return here (do nothing)
         Return
   }
   ; get ending linefeed (if any) where the offset is the length of the eol more than the starting position:
   StringGetPos, end, src, %eol%, , start + StrLen(eol)
   If ErrorLevel = 0 ; if this is not the last line (ending linefeed was found) then:
      StringTrimLeft, newEnd, src, end + 1 ; get trailing part of file
   StringLeft, newStart, src, start ;
   ; replace file contents
   FileDelete, %file%
   FileAppend, %newStart%%newEnd%, *%file% ; use * to preserve \n in Unix files
}

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 8:40 pm 
Offline

Joined: July 15th, 2007, 1:43 am
Posts: 1320
What about the "|" in the new file?

Edit:

You can get around this by setting the default eol as `r


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 16th, 2008, 12:54 pm 
Offline

Joined: October 1st, 2005, 2:09 am
Posts: 130
Location: Canada
Well, I tried all your guys' out, and ran into some problems. The main one would be, that sometimes it would not delete the file in time or some such, and then append the whole new block to the end of the original file.. this was a bad thing. Most notably this seemed to happen when it was deleting the last line of the file.

So, based on Chris', I wrote a function out of it.
Code:
FileDeleteLine(FileName, line_to_delete)
{
  Loop, Read, %FileName%, %FileName%.new
  {
    if A_Index <> %line_to_delete%
      FileAppend, %A_LoopReadLine%`n
  }
  FileMove, %FileName%.new, %FileName%, 1
}


I realise this is slower and more CPU intensive, but I have not run into any problems with it at all.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 16th, 2008, 1:46 pm 
Offline

Joined: May 27th, 2007, 9:41 am
Posts: 4999
Edit July 2009:
See TF.ahk A Library for Text file manipulation v2.3b or http://www.autohotkey.net/~hugov/tf-lib.htm for more functions.

How about this if you want to delete multiple lines?
Code:
FileDeleteLine("file.txt", "1,5,8,25") ; comma separated lines to delete

FileDeleteLine(FileName, line_to_delete)
{
  Loop, Read, %FileName%, %FileName%.new
  {
    if A_Index not in %line_to_delete%
      FileAppend, %A_LoopReadLine%`n
  }
  FileMove, %FileName%.new, %FileName%, 1
}


Last edited by SoLong&Thx4AllTheFish on August 6th, 2009, 9:14 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2008, 11:29 am 
Offline

Joined: October 1st, 2005, 2:09 am
Posts: 130
Location: Canada
And some further enhancements...
Code:
FileDeleteLine(FileName, line_to_delete)
{
  Loop, Read, %FileName%, %FileName%.new
  {
    if A_Index not in %line_to_delete%
      FileAppend, %A_LoopReadLine%`n
  }
  FileMove, %FileName%.new, %FileName%, 1
  if (ErrorLevel != 0)
    FileDelete, %FileName%.new
  Return %ErrorLevel%

}


So we can call it as Errors := FileDeleteLine(), and it will delete the temp file if there were problems. I like the idea of multiple lines, it's a neat way of modifying the code.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot] and 13 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group