Jump to content

Copy numbers from one .txt to another using StringRegExp


Recommended Posts

Hello guys,

First of all, I'm new to these forums, I decided to register because I couldn't solve the problem myself. I'm also new to Autoit but I have programming experience with Java, C and C#.

My problem is straight forward. Let me explain it in detail. When I start a program, a .txt file is generated, within it I'm interested in two specific numbers, these are:

  • VendorID and DeviceID

They are both located in the first two rows of the .txt file, and within quote marks, it looks like this:

  • "VendorID"     "123456"
  • "DeviceID"     "123456"

I'm trying to do the following:

  1. Start program
  2. Open .txt file, copy VendorID and DeviceID to variable
  3. Close program
  4. Save values to another .txt file that is similar to the one I opened but I only need to remove the old numbers with the new, same spot, same layout

I'm able to open the program, open the generated .txt file but when it all falls apart when I want to use StringRegExp to copy the numbers. I honestly don't understand how to format what it should copy, the function reference is confusing too, https://www.autoitscript.com/autoit3/docs/functions/StringRegExp.htm.

If anybody could guide me or help me with examples or code, it'd be very much appreciated. Thank you!

Link to comment
Share on other sites

Is the VendorID and DeviceID always in the first two rows of your target file as well?

With nothing on the lines except the desired information?

Yes, the source file looks like this:

"config"
{
    "VendorID"      "4098"
    "DeviceID"      "26545"

I will be copying the numbers and replacing them in an exact copy of the file but with a different name, the structure is the same.

EDIT: I'm sorry about the wrong information, it's the third and fourth lines not first two.

 

Edited by amdogelover
Link to comment
Share on other sites

Based on the steps you put in your post I wrote the code to do the same.  Just tried this and it worked on my test files.  You will of course need to modify for your data/paths.

$sSourceFile = @ScriptDir & "\Source.txt"
$sDestinationFile = @ScriptDir & "\Destination.txt"
$sProgramPath = "Your Program Path"
$sProcessName = "Your Program Process Name"

;Launch Program
Run($sProgramPath)

;Wait for our program to open
While 1
    Sleep(100)
    If ProcessExists($sProcessName) Then ExitLoop
WEnd

;Read Lines from Source File
$hSource = FileOpen($sSourceFile)
$sSourceLine2 = FileReadLine($hSource, 2)
$sSourceLine3 = FileReadLine($hSource, 3)
FileClose($hSource)

;Close Program
ProcessClose($sProcessName)

;Write Lines to Destination File
$sDestination = FileRead($sDestinationFile)
$hDestination = FileOpen($sDestinationFile, 2)
$sNewContent = StringRegExpReplace($sDestination, '("VendorID"\s+"\d+")', $sSourceLine2)
$sNewContent = StringRegExpReplace($sNewContent, '("DeviceID"\s+"\d+")', $sSourceLine3)
FileWrite($hDestination, $sNewContent)
FileClose($hDestination)

This could be simplified quite a bit more if I knew how your destination file was created.  If your manually creating that file you can put a static string in the file and use ReplaceStringInFile() instead of RegEx but I assumed that the destination file is like the source with a random VendorID/DeviceID so RegEx will find them and replace it from the lines in the source file.

Link to comment
Share on other sites

I will be copying the numbers and replacing them in an exact copy of the file but with a different name, the structure is the same.

If the 2 files have the same content except these numbers why don't you simply copy the whole source and overwrite the destination file ?

#include <FileConstants.au3>

$sSourceFile = @ScriptDir & "\Source.txt"
$sDestFile = @ScriptDir & "\Destination.txt"

$sSource = FileRead($sSourceFile)

$hDest = FileOpen($sDestFile, $FO_OVERWRITE)
FileWrite($hDest, $sSource)
FileClose($hDest)

 

Link to comment
Share on other sites

If the 2 files have the same content except these numbers why don't you simply copy the whole source and overwrite the destination file ?

#include <FileConstants.au3>

$sSourceFile = @ScriptDir & "\Source.txt"
$sDestFile = @ScriptDir & "\Destination.txt"

$sSource = FileRead($sSourceFile)

$hDest = FileOpen($sDestFile, $FO_OVERWRITE)
FileWrite($hDest, $sSource)
FileClose($hDest)

 

Heh if that is the case pretty sure you can just do FileCopy()

#include <FileConstants.au3>

$sSourceFile = @ScriptDir & "\Source.txt"
$sDestFile = @ScriptDir & "\Destination.txt"

FileCopy($sSourceFile, $sDestFile, $FC_OVERWRITE)

 

The only thing common between the three files I need is these two lines, the rest are not the same. Every time I make a hardware change these numbers change and I need to update the original config files so that the program recognizes the new hardware. I've edited your code a little but it works great ViciousXUSMC! I had to change the lines from 2 and 3 to 3 and 4 because it only copied the brackets otherwise. The only thing that's a little weird is that every time it copies and writes to another file it includes the spacing too, so after a few runs the copied text is in the middle of the document. It also dawned upon me that I could just copy the two lines entirely instead of trying to copy the numbers because, as I said before, the lines are identical.

ViciousXUSMC: What could be the spacing problem, my copying and pasting code is exactly what you wrote.

Thank you guys for your help and input :)

 

Link to comment
Share on other sites

Because you have space in the original document and grab the entire line, then place it in only where the text is with the regex. 

At first I was looking for a way  to use filewriteline and filereadline only to make it fast and simple without regex.  But since I am using RegEx anyways the best solution is probably to read with regex as well so change the code to be something like this:

#Include <StringConstants.au3>

$sSourceFile = @ScriptDir & "\Source.txt"
$sDestinationFile = @ScriptDir & "\Destination.txt"
$sProgramPath = "Your Program Path"
$sProcessName = "Your Program Process Name"

;Launch Program
Run($sProgramPath)

;Wait for our program to open
While 1
    Sleep(100)
    If ProcessExists($sProcessName) Then ExitLoop
WEnd
;Read Lines from Source File
$hSource = FileOpen($sSourceFile)
$sSource = FileRead($hSource)
$aVendorID = StringRegExp($sSource, '("VendorID"\s+"\d+")', $STR_REGEXPARRAYMATCH)
$aDeviceID = StringRegExp($sSource, '("DeviceID"\s+"\d+")', $STR_REGEXPARRAYMATCH)
FileClose($hSource)

;Close Program
ProcessClose($sProcessName)

;Write Lines to Destination File
$sDestination = FileRead($sDestinationFile)
$hDestination = FileOpen($sDestinationFile, 2)
$sNewContent = StringRegExpReplace($sDestination, '("VendorID"\s+"\d+")', $aVendorID[0])
$sNewContent = StringRegExpReplace($sNewContent, '("DeviceID"\s+"\d+")', $aDeviceID[0])
FileWrite($hDestination, $sNewContent)
FileClose($hDestination)

 

Edited by ViciousXUSMC
Link to comment
Share on other sites

Ahhhh See I did not even know about that function :)  

Was manually thinking how to write only a single line with FileWriteLine() and gave up because it was getting more complex than the regex solution.

With that combo I would imagine performance wise on small files it wont matter but if you had a HUGE file the Line methods would be faster because it can avoid scanning the entire file for regex matches.

Though I think at least on the read part I have it so that it will stop after the first match and would only need to add the optional count for the regexpreplace() to get back to the same type of efficiency. 

Thus it comes down to what method the user would prefer.

I like RegEx() better since it will negate any issues in line numbers changing. 

#Include <StringConstants.au3>

$sSourceFile = @ScriptDir & "\Source.txt"
$sDestinationFile = @ScriptDir & "\Destination.txt"
$sProgramPath = "Your Program Path"
$sProcessName = "Your Program Process Name"
$iReplaceCount = 1 ;0 For Global

;Launch Program
Run($sProgramPath)

;Wait for our program to open
While 1
    Sleep(100)
    If ProcessExists($sProcessName) Then ExitLoop
WEnd

;Read Lines from Source File
$hSource = FileOpen($sSourceFile)
$sSource = FileRead($hSource)
$aVendorID = StringRegExp($sSource, '("VendorID"\s+"\d+")', $STR_REGEXPARRAYMATCH)
$aDeviceID = StringRegExp($sSource, '("DeviceID"\s+"\d+")', $STR_REGEXPARRAYMATCH)
FileClose($hSource)

;Close Program
ProcessClose($sProcessName)

;Write Lines to Destination File
$sDestination = FileRead($sDestinationFile)
$hDestination = FileOpen($sDestinationFile, 2)
$sNewContent = StringRegExpReplace($sDestination, '("VendorID"\s+"\d+")', $aVendorID[0], $iReplaceCount)
$sNewContent = StringRegExpReplace($sNewContent, '("DeviceID"\s+"\d+")', $aDeviceID[0], $iReplaceCount)
FileWrite($hDestination, $sNewContent)
FileClose($hDestination)

 

Edited by ViciousXUSMC
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...