Jibberish Posted July 20, 2017 Posted July 20, 2017 Junior Programmer here... Not much experience with opening, changing and closing files. I am trying to replace strings in a Text file except StringReplace does not actually replace the text. Here is a sample of my code... expandcollapse popup#include <File.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> Local $iStrReturn = 0 Local $hFile Local $sText Local $sNewText ; Location of File to be read $sFileName = "C:\Temp\MyPlayer.exe.config" ; The default is FALSE. We want to change this to TRUE $bLoopChecked = True CheckBox() Func Checkbox() $hFile = FileOpen($sFileName,$FO_READ) ; Open file in read mode to get text If $hFile = -1 Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred when Opening the file.") Exit EndIf FileSetPos($hFile, 0, 0) ; No idea if I need to do this, grasping at straws $sText = FileRead($hFile) ; Read the file into $sText If $sText = 1 Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading/writing the file.") Exit Else FileClose($hFile) ; Finished reading the file into $sText, so close the file. FileFlush($hFile) ; Manual says to use FileFlush between File Close and Open so here it is EndIf MsgBox(0,"Before Replacement",$sText) ; Displays the text read from the file to make sure something is there. ; Loop Check If $bLoopChecked = True Then ; Find the string return > 0 for success $iStrReturn = StringInStr('"<add key="LoopCheckbox" value=""False" />"', "False") ;MsgBox(0,"", "LoopCheckBox is " & $iStrReturn) If $iStrReturn > 0 Then ; If StringInStr returned > 0 the it found the string! ; The Meat of the code. This is where we have to replace "False" with "True" $sNewText = StringReplace($sText, '"<add key="LoopCheckbox" value="False" />"', '"<add key="LoopCheckbox" value="True" />"') MsgBox(0,"After Replacement",$sNewText) ; Display the text to see if it worked. $hFile = FileOpen($sFileName,$FO_OVERWRITE) ; Reopen the file to write to it, overwriting everything. FileWrite($hFile,$sNewText) ; Write the text to the file FileClose($hFile) ; Close the file EndIf EndIf EndFunc This is the file I am reading... <?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/> </startup> <appSettings> <add key="LoopCheckbox" value="false"/> </appSettings> </configuration> I tried opening the file with $FO_UTF8 and $FO_UTF8_NOBOM but got errors opening the file. The MsgBox "After Replacement" shows the value is still false.
Moderators JLogan3o13 Posted July 21, 2017 Moderators Posted July 21, 2017 @Jibberish one of our Regex experts will doubtless wander along and provide something more elegant, but for a simple method this works well for me. For this example my file is sitting on the desktop, change your file path accordingly. Let me know if you have any questions: #include <File.au3> Local $aFile, $sText, $sFile = @DesktopDir & "\test.xml" _FileReadToArray($sFile, $aFile) For $a = 1 To $aFile[0] If StringInStr($aFile[$a], '"LoopCheckbox" value="false"') Then $sText = StringReplace(FileReadLine($sFile, $a), '="false"', '="true"') _FileWriteToLine($sFile, $a, $sText, 1) EndIf Next FrancescoDiMuro and JonnyQuy 2 "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum!
Trong Posted July 21, 2017 Posted July 21, 2017 (edited) maybe: Dedug version: expandcollapse popupGlobal $sFile = "C:\Temp\MyPlayer.exe.config" Global $bLoopChecked = True Local $sValueTrue = '<add key="LoopCheckbox" value="true"/>' Local $sValueFalse = '<add key="LoopCheckbox" value="false"/>' Local $xFileEncoding = FileGetEncoding($sFile), $xContent = FileRead($sFile) If @error Or Not FileExists($sFile) Then Exit MsgBox(48, "ERROR", "Read file error: " & $sFile) Local $sCheckTrue = StringInStr($xContent, $sValueTrue) Local $sCheckFalse = StringInStr($xContent, $sValueFalse) ConsoleWrite("- Before:" & @CRLF & $xContent & @CRLF) If $sCheckFalse And Not $bLoopChecked Then Exit MsgBox(48, "Set value to: " & $bLoopChecked, "But cureent LoopCheckbox=false") ElseIf $sCheckTrue And $bLoopChecked Then Exit MsgBox(48, "Set value to: " & $bLoopChecked, "But cureent LoopCheckbox=true") EndIf If $sCheckFalse And $bLoopChecked Then MsgBox(64, "Will Set value to: " & $bLoopChecked, "Cureent LoopCheckbox=false") $xContent = StringReplace($xContent, $sValueFalse, $sValueTrue) ;~ ConsoleWrite("-" & @extended & @CRLF) Else MsgBox(64, "Will Set value to: " & $bLoopChecked, "Cureent LoopCheckbox=true") $xContent = StringReplace($xContent, $sValueTrue, $sValueFalse) ;~ ConsoleWrite("-" & @extended & @CRLF) EndIf Local $hOpen = FileOpen($sFile, 2 + 8 + $xFileEncoding) FileWrite($hOpen, $xContent) FileClose($hOpen) ConsoleWrite("+ After:" & @CRLF & $xContent & @CRLF) If (StringInStr($xContent, $sValueTrue) And $bLoopChecked) Or (StringInStr($xContent, $sValueFalse) And Not $bLoopChecked) Then Exit MsgBox(64, "Set value to: " & $bLoopChecked, "Set value OK") Else Exit MsgBox(48, "Set value to: " & $bLoopChecked, "Set value ERROR") EndIf Product version: Global $sFile = "C:\Temp\MyPlayer.exe.config" Global $bLoopChecked = True If _SetLoopChecked($bLoopChecked, $sFile) Then MsgBox(64, "Set value to: " & $bLoopChecked, "Set value OK" & @CRLF & "File: " & $sFile) Else MsgBox(48, "Set value to: " & $bLoopChecked, "Set value ERROR" & @CRLF & "File: " & $sFile) EndIf Func _SetLoopChecked($iTrue, $sFile = @ProgramFilesDir & "\MyApp\MyPlayer.exe.config") Local $xFileEncoding = FileGetEncoding($sFile), $xContent = FileRead($sFile) If @error Or Not FileExists($sFile) Then Return SetError(1, 0, 0) Local $sValueTrue = '<add key="LoopCheckbox" value="true"/>' Local $sValueFalse = '<add key="LoopCheckbox" value="false"/>' Local $sCheckTrue = StringInStr($xContent, $sValueTrue) Local $sCheckFalse = StringInStr($xContent, $sValueFalse) If $sCheckFalse And Not $iTrue Then Return SetError(0, 1, 1) ElseIf $sCheckTrue And $iTrue Then Return SetError(0, 1, 1) EndIf If $sCheckFalse And $iTrue Then $xContent = StringReplace($xContent, $sValueFalse, $sValueTrue) Else $xContent = StringReplace($xContent, $sValueTrue, $sValueFalse) EndIf Local $hOpen = FileOpen($sFile, 2 + 8 + $xFileEncoding) Local $WOK = FileWrite($hOpen, $xContent) FileClose($hOpen) If $WOK And ((StringInStr($xContent, $sValueTrue) And $iTrue) Or (StringInStr($xContent, $sValueFalse) And Not $iTrue)) Then Return SetError(0, 0, 1) Return SetError(2, 0, 0) EndFunc ;==>_SetLoopChecked Edited July 21, 2017 by Trong add version Regards,
FrancescoDiMuro Posted July 21, 2017 Posted July 21, 2017 6 hours ago, JLogan3o13 said: @Jibberish one of our Regex experts will doubtless wander along and provide something more elegant, but for a simple method this works well for me. For this example my file is sitting on the desktop, change your file path accordingly. Let me know if you have any questions: #include <File.au3> Local $aFile, $sText, $sFile = @DesktopDir & "\test.xml" _FileReadToArray($sFile, $aFile) For $a = 1 To $aFile[0] If StringInStr($aFile[$a], '"LoopCheckbox" value="false"') Then $sText = StringReplace(FileReadLine($sFile, $a), '="false"', '="true"') _FileWriteToLine($sFile, $a, $sText, 1) EndIf Next @JLogan3o13 Always the smartest code Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette
Moderators JLogan3o13 Posted July 21, 2017 Moderators Posted July 21, 2017 Or you could go with @Trong's Rube Goldberg script antonioj84 1 "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum!
Jibberish Posted July 21, 2017 Author Posted July 21, 2017 Wow! The support here is amazing! I'll try all these out and try to understand why these work and mine doesn't. Always learning...! Cheers, Jibberish
antonioj84 Posted January 22, 2018 Posted January 22, 2018 (edited) On 7/20/2017 at 8:40 PM, JLogan3o13 said: @Jibberish one of our Regex experts will doubtless wander along and provide something more elegant, but for a simple method this works well for me. For this example my file is sitting on the desktop, change your file path accordingly. Let me know if you have any questions: #include <File.au3> Local $aFile, $sText, $sFile = @DesktopDir & "\test.xml" _FileReadToArray($sFile, $aFile) For $a = 1 To $aFile[0] If StringInStr($aFile[$a], '"LoopCheckbox" value="false"') Then $sText = StringReplace(FileReadLine($sFile, $a), '="false"', '="true"') _FileWriteToLine($sFile, $a, $sText, 1) EndIf Next about if I just wanted to replace value value=" 10.23.25.16" and the value may not necessarily be value=" 10.23.25.16", it could change there the idea is to replace anything after value=" " <?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/> </startup> <appSettings> <add key="LoopCheckbox" value="10.23.25.16"/> </appSettings> </configuration Edited January 22, 2018 by antonioj84 correction
mikell Posted January 22, 2018 Posted January 22, 2018 ? $txt = StringRegExpReplace(FileRead("test.xml"), '(?<=LoopCheckbox" value=")[^"]*', "anything") Msgbox(0,"test", $txt)
antonioj84 Posted January 22, 2018 Posted January 22, 2018 (edited) <!-- BEGIN connector for Tender Retail --> <CONNECTOR name="TenderRetailConnector" javaclass="rci.retail.stores.commext.connector.tenderretail.RCITenderRetailConnector"> <PROPERTY propname="hostname" propvalue="127.1.1.1" /> <PROPERTY propname="portNumber" propvalue="3858" proptype="INTEGER" /> <PROPERTY propname="timeout" propvalue="180000" proptype="INTEGER" /> </CONNECTOR> </CONNECTORS> here is my xml pattern, the value i m after to replace is "127.1.1.1" thanks for your help 2 hours ago, mikell said: ? $txt = StringRegExpReplace(FileRead("test.xml"), '(?<=LoopCheckbox" value=")[^"]*', "anything") Msgbox(0,"test", $txt) Edited January 22, 2018 by antonioj84 error
antonioj84 Posted January 22, 2018 Posted January 22, 2018 $sFile = @ScriptDir & '\Manager.xml' FileSetAttrib($sFile & '\Manager.xml', "-R") ; remove flag make file editable _FileReadToArray($sFile, $aFile) ;_ArrayDisplay($aFile) For $a = 1 To $aFile[0] If StringInStr($aFile[$a], '"hostname" propvalue="127.1.1.1"') Then $sText = StringReplace(FileReadLine($sFile, $a), '="127.1.1.1"','="127.2.2.2"') MsgBox(0,'',$sText) _FileWriteToLine($sFile, $a, $sText, 1) EndIf Next this current code works, all i need is to be able to replace anything after propvalue="" with another value example 127.2.2.2 thankd
mikell Posted January 22, 2018 Posted January 22, 2018 Why didn't you provide the real xml first ? $new = "127.2.2.2" $txt = StringRegExpReplace(FileRead("test.xml"), '(?<=hostname" propvalue=")[^"]*', $new) Msgbox(0,"test", $txt) antonioj84 1
AspirinJunkie Posted January 22, 2018 Posted January 22, 2018 Because it's an xml-file so why not handle it as an xml-file?: ; load XMLDOM-object Local $o_XML = ObjCreate("Microsoft.XMLDOM") ; try to load xml from file If Not $o_XML.load("MyPlayer.exe.config") Then Exit MsgBox(48, "Error", "error when opening file") ; pick node (with XPath-selector) and directly set the new attribute value $o_XML.SelectSingleNode('//add[@key="LoopCheckbox"]').setAttribute("value", "true") ; write out the xml: $o_XML.save("Out.config") ConsoleWrite($o_XML.xml() & @CRLF)
antonioj84 Posted January 26, 2018 Posted January 26, 2018 (edited) On 1/22/2018 at 8:26 AM, mikell said: Why didn't you provide the real xml first ? $new = "127.2.2.2" $txt = StringRegExpReplace(FileRead("test.xml"), '(?<=hostname" propvalue=")[^"]*', $new) Msgbox(0,"test", $txt) if i were to read a second node adding same ip, this does not work below. thanks ahead $new = "127.2.2.2" while 1 $txt = StringRegExpReplace(FileRead("test.xml"), '(?<=hostname" propvalue=")[^"]*', $new) $txt = StringRegExpReplace(FileRead("test.xml"), '(?<=hostname3" propvalue3=")[^"]*', $new) ; how do i read next Msgbox(0,"test", $txt) if @error = -1 then exitloop wend Edited January 26, 2018 by antonioj84 error
mikell Posted January 26, 2018 Posted January 26, 2018 Hey, you posted just a part of the xml and asked a partial question, so you got a partial answer As I said before, post the whole xml with all the replacements to do and you will get a complete answer
antonioj84 Posted January 26, 2018 Posted January 26, 2018 (edited) #RequireAdmin #include<file.au3> #include<array.au3> local $Jpos = @ScriptDir & "\Jpos.xml", $aFile,$sText FileSetAttrib($Jpos, "-R") _FileReadToArray($Jpos, $aFile) ;_ArrayDisplay($aFile) For $a = 1 To $aFile[0] If StringInStr($aFile[$a], '"PortName" "String" value="0.0.0.0"') Then $sText = StringReplace(FileReadLine($Jpos, $a), '="0.0.0.0"','="127.2.2.2"') MsgBox(0,'',$sText) _FileWriteToLine($Jpos, $a, $sText, 1) EndIf Next the Problem here is what I am trying to do is to change the whole xlm file at the 2 locations anywhere it encounter PortName value=" anything" <JposEntry logicalName="CashDrawer"> <prop name="PortName" type="String" value="0.0.0.0"/> </JposEntry> <JposEntry logicalName="POSPrinter"> <prop name="PortName" type="String" value="0.0.0.0"/> </JposEntry> Edited January 26, 2018 by antonioj84 error
mikell Posted January 26, 2018 Posted January 26, 2018 Hmmm it's different from the previous requirement again ... $new = "127.2.2.2" $txt = StringRegExpReplace(FileRead("test.xml"), '(?m)^.*PortName.*value="\K[^"]*', $new) Msgbox(0,"test", $txt) antonioj84 1
antonioj84 Posted January 27, 2018 Posted January 27, 2018 14 hours ago, mikell said: Hmmm it's different from the previous requirement again ... $new = "127.2.2.2" $txt = StringRegExpReplace(FileRead("test.xml"), '(?m)^.*PortName.*value="\K[^"]*', $new) Msgbox(0,"test", $txt) Thanks
Moderators JLogan3o13 Posted January 27, 2018 Moderators Posted January 27, 2018 @antonioj84 please stop quoting the previous text every...single...response. Just hit reply; we know what we said, and it pads the thread needlessly. antonioj84 1 "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum!
antonioj84 Posted January 27, 2018 Posted January 27, 2018 let me share this piece of snippet, the regex look for the ip pattern in the file and replace the ip address. The 1 is the count, if left empty it will change ip until the end of the file #include <File.au3> #include <Array.au3> _ChangeIP("127.1.1.1") Func _ChangeIP($sNewIPAddress) Local $iRet = 0 Local $sFile = @ScriptDir & '\Manager.xml' FileSetAttrib($sFile & '\Manager.xml', "-R") ; remove flag make file editable Local $sData = FileRead($sFile) Local $hFile = FileOpen($sFile, 2) $sData = StringRegExpReplace($sData, '\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b', $sNewIPAddress, 1) ; 2 count change ip twice $iRet = @extended FileWrite($hFile, $sData) FileClose($hFile) Return $iRet EndFunc ;==>_ChangeIP
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