Jump to content

Replace Strings from Another Txt File - (Moved)


Recommended Posts

Hi,

I have a 1.txt file like this;

M211 S0;
G90;
G01 X12.8356Y4.2664
G01 X12.8404Y4.2176
G04 P500;
G1 F60
G00 Z2.0000
G00 X8.5161Y8.8562
G01 Z-0.0700
G01 X12.8350Y4.5373
G01 X12.8350Y4.2909
G01 X12.8500Y4.1694
G01 X12.8642Y4.1225
G01 X12.8830Y4.0771
...

and i have 2.txt file like this;

M211 S0;
G90;
G04 P500
G1 F60
...

I want the lines in this second file to be deleted from the first file. So I want to get a result like this;

G01 X12.8356Y4.2664
G01 X12.8404Y4.2176
G00 Z2.0000
G00 X8.5161Y8.8562
G01 Z-0.0700
G01 X12.8350Y4.5373
G01 X12.8350Y4.2909
G01 X12.8500Y4.1694
G01 X12.8642Y4.1225
G01 X12.8830Y4.0771
...

 

I can replace strings with the code down below. But I don't know how I can get the lines from the second txt file.

#include <File.au3>
_ReplaceStringInFile ( "c:\textfile.txt", "exampleString", "replaceString", $STR_NOCASESENSE)

 

I would be very happy if you can help

 

Link to post
Share on other sites
  • Moderators

Moved to the appropriate forum.

Moderation Team

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to post
Share on other sites
  • Moderators

ahmetpi,

A simple way to do this would be to read the second file into an array and then loop through it replacing each line one at a time in the main file. Reading both files into arrays would probably be faster.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to post
Share on other sites

Here's one way to accomplish that.

#include <File.au3>
#include <Array.au3>

Global $aDataArr, $aDeleteArr, $aDataArrCleared[0], $bFound
_FileReadToArray(@ScriptDir & "\DataArr.txt", $aDataArr, $FRTA_NOCOUNT)
_FileReadToArray(@ScriptDir & "\DeleteArr.txt", $aDeleteArr, $FRTA_NOCOUNT)
For $i = 0 To UBound($aDataArr) -1
    $bFound = False
    For $k = 0 To UBound($aDeleteArr) -1
        If $aDataArr[$i] == $aDeleteArr[$k] Then
            $bFound = True
            ExitLoop
        EndIf
    Next
    If Not $bFound Then _ArrayAdd($aDataArrCleared, $aDataArr[$i])
Next
_ArrayDisplay($aDataArrCleared, "Cleared File :") ; just for testing
_FileWriteFromArray(@ScriptDir & "\DataArrCleared.txt", $aDataArrCleared)
18 hours ago, ahmetpi said:

I want the lines in this second file to be deleted from the first file.

DataArr.txt = the first file

DeleteArr.txt = the second file

DataArrCleared.txt = new file without the lines from DeleteArr.txt.

BTW : G04 P500; is different from G04 P500 and therefore will not be removed ! 

DeleteArr.txt DataArr.txt

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to post
Share on other sites

@ahmetpi
For the fun :)

Non-compact version:

Spoiler
#include <File.au3>
#include <StringConstants.au3>

Test()

Func Test()

    Local $strSourceFileName = @ScriptDir & "\TestFiles\SourceFile.txt", _
          $strReplaceFileName = @ScriptDir & "\TestFiles\ReplaceFile.txt", _
          $strDestFileName = @ScriptDir & "\TestFiles\DestFile.txt", _
          $strSourceFileContent = "", _
          $strReplaceFileContent = "", _
          $strDestFileContent = "", _
          $strPattern = "", _
          $arrResult


    $strSourceFileContent = FileRead($strSourceFileName)
    If @error Then Return ConsoleWrite("FileRead ERR: " & @error & @CRLF)

    $strReplaceFileContent = FileRead($strReplaceFileName)
    If @error Then Return ConsoleWrite("FileRead ERR: " & @error & @CRLF)

    $strPattern = '(' & StringReplace($strReplaceFileContent, @CRLF, '\R?|') & '\R?)'

    $strDestFileContent = StringRegExpReplace($strSourceFileContent, $strPattern, '')

    FileWrite($strDestFileName, $strDestFileContent)
    If @error Then Return ConsoleWrite("FileWrite ERR: " & @error & @CRLF)

EndFunc

 

Compact version:

Spoiler
#include <File.au3>
#include <StringConstants.au3>

Test()

Func Test()

    Local $strSourceFileName = @ScriptDir & "\TestFiles\SourceFile.txt", _
          $strReplaceFileName = @ScriptDir & "\TestFiles\ReplaceFile.txt", _
          $strDestFileName = @ScriptDir & "\TestFiles\DestFile.txt"

    Return FileWrite($strDestFileName, StringRegExpReplace(FileRead($strSourceFileName), '(' & StringReplace(FileRead($strReplaceFileName), @CRLF, '\R?|') & '\R?)', ''))

EndFunc

 

P.S.: you were missing a ; after the "G04 P500" line in your replacement file (as @Musashi already pointed you out) ^_^

Edited by FrancescoDiMuro

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to post
Share on other sites

Hi all :)
A few days ago I experimented successfully for the 1st time the instruction _ArrayDelete() when its 2nd parameter is an Array and it worked fast & nicely on an Array containing 1000 rows.

For example, in OP's need, it could be done like this (Array names are Musashi's)

_ArraySort($aDataArr) ; ascending, required for coming _ArrayBinarySearch()

For $i = 1 To $aDeleteArr[0] ; [0] = number of rows in array $aDeleteArr
    $idx = _ArrayBinarySearch($aDataArr, $aDeleteArr[$i]) ; extremely fast (+++)
    If $idx = -1 Then Exit MsgBox(0, "", "_ArrayBinarySearch failed")
    $aDeleteArr[$i] = $idx
Next

_ArrayDelete($aDataArr, $aDeleteArr) ; delete using a 1D array with a count in the [0] element (at last !)

Of course there is the problem of "If $idx = -1" that could never happen in my own script (where the user selected several existing rows to be deleted after pressing the Del Key) but I still wanted to share this idea with you :)

Just tried it again on a 2000 rows source file and 100 rows to be deleted, it was very fast.

Link to post
Share on other sites
5 hours ago, pixelsearch said:

A few days ago I experimented successfully for the 1st time the instruction _ArrayDelete() when its 2nd parameter is an Array and it worked fast & nicely on an Array containing 1000 rows.

First of all : I really like this approach, thanks for sharing :).

In this particular case, however, some problems are occurring :

  • It does not work, if $aDeleteArr contains a vValue that does not exist in the $aDataArr (@error=3 , as described in the help, so the error message is ok :)). This is the case here, because the OP probably made a typo : DeleteArr = G04 P500 -> DataArr = G04 P500;
  • (after fixing this typo - @ahmetpi : you have to fix this as well !) : Instead of $idx = _ArrayBinarySearch($aDataArr, $aDeleteArr[$i]) , I had to use $idx = _ArrayBinarySearch($aDataArr, $aDeleteArr[$i], 1).
  • If there are several identical entries (here : G90;) only the first one will be removed. However, this was not an original request by the OP, I just added these data for testing purposes (so it can be ignored). Other users should pay attention to it, though.

Here is the new combined script : (the lines with  ; *** Musashi : just for testing are for control reasons only and can be removed)

#include <File.au3>
#include <Array.au3>
Global $aDataArr, $aDeleteArr
_FileReadToArray(@ScriptDir & "\DataArr.txt", $aDataArr)
_FileReadToArray(@ScriptDir & "\DeleteArr.txt", $aDeleteArr)
_ArraySort($aDataArr) ; ascending, required for coming _ArrayBinarySearch()

For $i = 1 To $aDeleteArr[0] ; [0] = number of rows in array $aDeleteArr
    ConsoleWrite(" ==> $i=" & $i & "  vValue=" & $aDeleteArr[$i] & @CRLF) ; *** Musashi : just for testing
    $idx = _ArrayBinarySearch($aDataArr, $aDeleteArr[$i], 1) ; extremely fast (+++)
    ConsoleWrite(" ----> Error=" & @error & "  $idx=" & $idx & "  vValue=" & $aDeleteArr[$i] & @CRLF) ; *** Musashi : just for testing
    If $idx = -1 Then Exit MsgBox(0, "", "_ArrayBinarySearch failed")
    $aDeleteArr[$i] = $idx
Next

_ArrayDelete($aDataArr, $aDeleteArr) ; delete using a 1D array with a count in the [0] element (at last !)
_ArrayDisplay($aDataArr, "Cleared Array :") ; *** Musashi : just for testing

 

5 hours ago, pixelsearch said:

Of course there is the problem of "If $idx = -1" that could never happen in my own script

Yes, one has to really make sure that "reliable data" are available ;).

 

Edited by Musashi

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to post
Share on other sites
  • Moderators

Hi,

Using _ArrayDelete with either a range string or an array means that you get multiple deletions with only a single ReDim call - and as everyone (I hope) knows that is the real bottleneck in any array manipulation code. Delighted to see that my hard work to update the function a while back is appreciated - even if it has taken this long for the improvement to be noticed!

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to post
Share on other sites
Local $o_File1 = 'M211 S0;' & @CRLF & _
            'G90;' & @CRLF & _
            'G01 X12.8356Y4.2664' & @CRLF & _
            'G01 X12.8404Y4.2176' & @CRLF & _
            'G04 P500;' & @CRLF & _
            'G1 F60' & @CRLF & _
            'G00 Z2.0000' & @CRLF & _
            'G00 X8.5161Y8.8562' & @CRLF & _
            'G01 Z-0.0700' & @CRLF & _
            'G01 X12.8350Y4.5373' & @CRLF & _
            'G01 X12.8350Y4.2909' & @CRLF & _
            'G01 X12.8500Y4.1694' & @CRLF & _
            'G01 X12.8642Y4.1225' & @CRLF & _
            'G01 X12.8830Y4.0771'

Local $o_File2 = 'M211 S0;' & @CRLF & _
            'G90;' & @CRLF & _
            'G04 P500' & @CRLF & _
            'G1 F60'

Local $0_Pattern = StringReplace($o_File2, @CRLF, "$|^")
$0_Pattern = '(?m)^' & $0_Pattern & '$'

Local $0_Output = StringRegExpReplace($o_File1, $0_pattern, "")

local $0_Space = "(?m)^[\s]+"
$0_Output = StringRegExpReplace($0_Output, $0_Space, "")
MsgBox(0, "", $0_Output)

 

Link to post
Share on other sites

Alternative way using  Scripting.Dictionary

#include <Array.au3>

$aDataArr = FileReadToArray(@ScriptDir & "\1.txt")
$aDeleteArr = FileReadToArray(@ScriptDir & "\2.txt")
$sd1 = ObjCreate("Scripting.Dictionary")
$sd2 = ObjCreate("Scripting.Dictionary")
For $i In $aDataArr
    $sd1.Item($i)
Next
For $i In $aDeleteArr
    If $sd1.Exists($i) Then $sd1.Remove($i)
Next
$aDataArrCleared = $sd1.Keys()
_ArrayDisplay($aDataArrCleared, "Cleared File :")

 

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...