emendelson Posted July 28, 2009 Posted July 28, 2009 Is there a routine in AutoIt that will read a text file and tell me the line number (or numbers) of any line that contains a specific string? I am looking for this (or something like it) because I want to open %systemroot%\system32\autoexec.nt and find any line that contains "tame-nt.com" (any line which does NOT start with REM or a colon but contains that string), and then temporarily add REM the start of that line (or lines) and write the file to disk; I then want to perform some other operations in a script; and finally I want to remove the REM that I added to the line so that the autoexec.nt file ends up the way it started. (The reason for this that the current version of the Tame utility which speeds up 16-bit DOS applications - see www.tamedos.com - crashes when certain operations are performed by a script that I've been using for years, and I want to prevent Tame from loading when those specific operations are performed, but only when those operations are performed.) The easiest way to do this seems to be to know the line number and use FileWrite to modify the line. Or is there a simpler method that I haven't been able to think of? Thanks for any help.
GEOSoft Posted July 28, 2009 Posted July 28, 2009 Is there a routine in AutoIt that will read a text file and tell me the line number (or numbers) of any line that contains a specific string? I am looking for this (or something like it) because I want to open %systemroot%\system32\autoexec.nt and find any line that contains "tame-nt.com" (any line which does NOT start with REM or a colon but contains that string), and then temporarily add REM the start of that line (or lines) and write the file to disk; I then want to perform some other operations in a script; and finally I want to remove the REM that I added to the line so that the autoexec.nt file ends up the way it started. (The reason for this that the current version of the Tame utility which speeds up 16-bit DOS applications - see www.tamedos.com - crashes when certain operations are performed by a script that I've been using for years, and I want to prevent Tame from loading when those specific operations are performed, but only when those operations are performed.)The easiest way to do this seems to be to know the line number and use FileWrite to modify the line. Or is there a simpler method that I haven't been able to think of?Thanks for any help.There are a couple of ways to do ths but no single function that will return the line number. Probably the easiest is to use _FileReadToArray(), correct the elements (see StringInStr() for this) and then _FileWriteFromArray(). My personal preference would be to use FileRead() followed by StringRegExpReplace() to correct the strings then FileWrite(). Be carefull when you add the REM to those lines if there are already REMed lines containing that string. If you attempt to write a script to undo the changes you will also remove the existing REMs. I would use "REM ~" or something along those lines so that you can undo it with a simple StringReplace(). George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
Malkey Posted July 28, 2009 Posted July 28, 2009 (edited) This is a non-conventional method, but this example appears to work. expandcollapse popup; #include <File.au3> #include <array.au3> Local $sFileName = "test.txt" Local $searchStr = "sk" $aResult = _LineNumsOfSearchStr($sFileName, $searchStr, False) _ArrayDisplay($aResult) ; Returns array of found line numbers that contain $searchStr contents. ; Optional delete found line from file. Func _LineNumsOfSearchStr($sFileName, $searchString, $bDeleteLine = False) Local $location, $aCurrentLineNum, $iCurrentLineNum, $sFile, $iOccur = 1, $sRes = "" If FileExists($sFileName) = 0 Then Return 1 Do $sFile = FileRead($sFileName) $location = StringInStr($sFile, $searchString, 0, $iOccur) ; Find the $iOccur occurrence of the "substring" If $location > 0 Then $aCurrentLineNum = StringRegExp(StringRegExpReplace($sFile, "(?s)(.{" & $location & "})(.*)$", "\1"), "(?s)(\v+)", 3) ;Find line number $iCurrentLineNum = UBound($aCurrentLineNum) + 1 ; Line number ;ConsoleWrite("CharPos: " & $location & " Ln: " & $iCurrentLineNum & @CRLF) $sRes &= $iCurrentLineNum & "|" If $bDeleteLine Then _FileWriteToLine($sFileName, $iCurrentLineNum, "", 1) ; Remove found line from file. Else $iOccur += 1 EndIf Else ExitLoop EndIf Sleep(10) Until 0 ;ShellExecute($sFileName) Return StringSplit(StringTrimRight($sRes, 1), "|") EndFunc ;==>_LineNumsOfSearchStr ; Edit: Removed Quote. Edited July 28, 2009 by Malkey
GEOSoft Posted July 28, 2009 Posted July 28, 2009 Actually I was just giving this somemore thought and it's okay to put a REM ~ infront of an existing REM statement so that makes it simple. $sFile = @SystemDir & "\autoexec.nt" $sStr = FileRead($sFile) $sStr = StringRegExpReplace($sStr, "(?i)(.*tame\-nt\.com.*)", "REM ~$1") If @Extended Then $hFile = FileOpen($sFile, 2) FileWrite($hFile, $sStr) FileClose($hFile) EndIf To Undo the changes would be similar $sFile = @SystemDir & "\autoexec.nt" $sStr = FileRead($sFile) $sStr = StringReplace($sStr, "REM ~", "") If @Extended Then $hFile = FileOpen($sFile, 2) FileWrite($hFile, $sStr) FileClose($hFile) EndIf George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
emendelson Posted July 29, 2009 Author Posted July 29, 2009 Actually I was just giving this somemore thought and it's okay to put a REM ~ infront of an existing REM statement so that makes it simple.Many, many thanks - this is simple and elegant and does EXACTLY what I was hoping to find. I'll incorporate it in my script immediately.
GEOSoft Posted July 29, 2009 Posted July 29, 2009 (edited) Many, many thanks - this is simple and elegant and does EXACTLY what I was hoping to find. I'll incorporate it in my script immediately. Glad it helped. Tip: If you are incorporating that into a full script then put the code into separate functions Func _RemLines() ;; First code block in here EndFunc Func _UnRemLines() ;; Second code block EndFunc You could also make those functions more usable. Instead just limiting them to tame-nt.com set a parameter in the first function that tells te RegExpReplace what to search for. It will only take one extra line of RegExpReplace code to escape any characters that have to be escaped. If you did that you could call the function like this _RemLines("tame-nt.com") Func _RemLines($sFind) ;; Line to escape characters, I think this will work fine $sFind = StringRegExpReplace($sFind, "([[:punct:]])", "\\$1") ;; First code block in here with the line $sStr = StringRegExpReplace($sStr, "(?i)(.*tame\-nt\.com.*)", "REM ~$1") ;; changed to ;; $sStr = StringRegExpReplace($sStr, "(?i)(.*" & $sFind & ".*)", "REM ~$1") EndFunc Edited July 29, 2009 by GEOSoft George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
emendelson Posted July 29, 2009 Author Posted July 29, 2009 Thanks again for that - I had already put the code in function blocks (I need to use each block four times in this script), but hadn't thought about using tame-nt.com as a parameter to make it easier to re-use the code. Will do that now - and again, many thanks for elegant code that does precisely what was needed. I think these snippets would be useful to other people also.
DeltaRocked Posted October 11, 2012 Posted October 11, 2012 (edited) @Malkey @Geosoft you guys are awesome. for the first time I have seen regex being used to extract line nos. I never knew this was possible. From me 5 stars. Regards Deltar Edited October 20, 2012 by deltar
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now