Link to home
Start Free TrialLog in
Avatar of Matty
Matty

asked on

Change text in file in specific location without changing other occurrences of same text in other locations in the file

Please I need help with below 2 scripting challenges I am facing. I am using

UFT 12.5




Chalenge 1.

I want to be able to replace a text in a text file in a specific location




For Example.




Let say I have a text file that contains the following "I bought a car and I bought a shoe and I bought a Laptop"




I need I script that can read this text file and only change "I bought a shoe" to I sold a Shoe"




The end result of my text file will be "I bought a car and I sold a shoe and I bought a Laptop"


Please Note that the text file has more than one line of text . I want to be able to change any text of interest based on the location of the text in the file while not changing other occurrences of the same text in other locations of the file.
Below script I used does a replace all and that is not what I want. So How can I modify below script to give me what I want





Const ForReading = 1

Const ForWriting = 2


Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("C:\Scripts\Text.txt", ForReading)


strText = objFile.ReadAll

objFile.Close

strNewText = Replace(strText, "Jim ", "James ")


Set objFile = objFSO.OpenTextFile("C:\Scripts\Text.txt", ForWriting)

objFile.WriteLine strNewText

objFile.Close




Set objFSO = Nothing
Avatar of Norie
Norie

Matt

How is the location of the text to change determined/set?

Is it always the 2nd occurrence of a specific term?

For example, based on your question, the 2nd occurrence of 'bought' in the text file?
Here's an enhancement to your posted script that let's you process each line individually and decided when to replace.  As written it only does the replace on the second line (index 1 because arrays are 0 based).  Adjust the logic as you need.

The basic idea is it reads all the data from the file, splits it into an array at line breaks, you update any array elements (lines) needed, and then it joins them back to a text string, and writes it back to the file.  Hope this helps...

Const ForReading = 1
Const ForWriting = 2

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("C:\Scripts\Text.txt", ForReading)
strText = objFile.ReadAll
objFile.Close

arrLines = Split(strText, vbCrLf)

For i = 0 To UBound(arrLines)

    If arrLines(i) <> "" Then
        If i = 1 Then
            arrLines(i) = Replace(arrLines(i), "Jim ", "James ")
        End If
    End If

Next

strText = Join(arrLines, vbCrLf)

Set objFile = objFSO.OpenTextFile("C:\Scripts\Text.txt", ForWriting)
objFile.Write strText
objFile.Close

Set objFSO = Nothing

Open in new window


»bp
Avatar of Matty

ASKER

Hi Bill,

Thanks for the quick response. Problem with the update you made is that it will replace all occurrence of "Jim" with James on any given text Line that you choose. That is if you have a text file with below data:
Jim Jones is      Jimson   James
Mary DoeJim is gone
Jimmie is  Doe Jones
Jimsmith Johnson is JamesJim

Let say you want to change the first line  text of "Jimson"    to   "Jamesson"  basically given an out put for the first line to be "Jim Jones is      Jamesson   James"   which is what I want.  The update you made will not achieve that instead it will give me
"James Jones is      Jamesson   James"  which is not what I want .

Any assistance will be highly appreciated.

Thanks
Matt

In your latest example you appear to want to change only the first occurrence of a term in the first line of the file.

So is there some logic/pattern/rule for what you want to do?

Do you want code that you can pass arguments to which will determine what to replace, what to replace it with, where to replace it , e.g. which row etc?
Once we fully (let me repeat, fully) understand what the replacement logic should be we can code for that.  It might be refining the Replace() or a Regex() approach might be better.  But we will need to understand the exact rules for the replacement, that will always work.


»bp
What other example do you have? For the above, you can do this
Option Explicit

Dim strText

strText = "I bought a car and I bought a shoe and I bought a Laptop"
strText = Replace(strText, "I bought a shoe", "I sold a Shoe")
WScript.Echo strText

Open in new window

Avatar of Matty

ASKER

Thanks Bill and Norie,

Following the example I gave with below text file:

Jim Jones is      Jimson   James
Mary DoeJim is gone
Jimmie is  Doe Jones
Jimsmith Johnson is JamesJim

The logic will be that I will like to locate a know text, in this case Jim occurring in a particular position of the file in this example position 18 to 20 and I want to replace it with a know text in this case James

I can later decide to change another word Jim in the same file with a totally different word . Example I can also decide to change the text Jim in the second line which is in position 9 to 11 with a work like Vegas without changing any other occurrence of Jim in the file.

I can do the same with any other text in the file like smith, etc

Please kindly let me know if I need to clarify further.

Again that you so much for your quick response. I must say that I am already impressed with this forum. I just joined few hours ago and I am already getting response. I mean quick response

Thanks a lot
Avatar of Matty

ASKER

Hi Bill

I got below code from the web, however I do not understand how the Regex is used. I am wondering is there a way to tweek the regex portion of this code to help solve my issue. I know with MID function you can define the starting position of a string and the number of charaters you want from that postion, not sure why it is not possible like wise to change that particular string only that you can identify with MID function.

Below is the code with regex that I am wondering whether the regex piece can be tweeked to help solve my problem.

'Using Reg Expression
'Please change the path to your file to suit in this line
StrFileName = "C:\temp\log.txt"
Const ForReading = 1    
Const ForWriting = 2
Dim objFSO
Dim objTF
Dim objRexex
Dim StrFileName
Dim strTxt

StrFileName = "C:\temp\log.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTF = objFSO.OpenTextFile(StrFileName, ForReading)
Set objregex = CreateObject("vbscript.regexp")
strTxt = objTF.ReadAll
objTF.Close
With objregex
    .Global = True
    .MultiLine = True
    .Pattern = "^(.{8})[^-](.*)$"
    strTxt = .Replace(strTxt, "$1" & "-" & "$2")
End With

Set objTF = objFSO.OpenTextFile(StrFileName, ForWriting)
objTF.Write strTxt
objTF.Close


Your continued assistance is highly appreciated.
Avatar of Matty

ASKER

I was thinking that if we can get any specifc string with MID Function that we can also replace a specific string  in a particular position or location in a text file without replacing other occurrences of that string that exists in other locations of the text file. That is the problem I am trying to solve. To replace a string in a specific location without replacing it's occurrence in other locations in the text file.

Thanks again for your continued assistance
Following the example I gave with below text file:

Jim Jones is      Jimson   James
Mary DoeJim is gone
Jimmie is  Doe Jones
Jimsmith Johnson is JamesJim

I still haven't seen a clear enough set of "rules" to use for the replace to codify it.  You say "in this example position 18 to 20", but I expect that could change for other lines / files?  

Are you only changing one file, or many with this script?

Would the part of the line you want to change always come after the " is " in your example, or could that change?

You need a set of constraints that will be true in all conditions.

Also, you have mentioned case sensitivity I don't think, is that a requirement, or case insensitive replacements?

Also, would the text you want to replace always be preceded by a space, or not always?

Etc...


»bp
Avatar of Matty

ASKER

Bill,

Thank you for your patient with me. May the solution I am looking for is not possible with vbscript.  Now let me try an explain more . Let's say we have a flat file as shown below with column headers as name, age, sex, city, profession:
james 28 m london student
Joan 24 f paris civil Engineer
jimmy 30 m delhi teacher
tanya 36 f London attorney

If I want to read the age  of each person . The age of James is 28 and city of london, Joan is 24 from paris, Jimmy is 30  from delhi and tanya is 36 from london.  Now the requirement is to update this file to change their age and their city so that the end result will look like below text file after the update:

james 20 m london student
Joan 43 f Baltimore civil Engineer
jimmy 39 m New York teacher
tanya 36 f Vegas attorney


Please how can this be solved with the code you sent me before.  This is very similar to what I am trying to solve. Any assistance will be appreciated

Thanks
So are you working with a delimited file then?  If so, what is the delimiter, your header line seemed to use a comma, where the data lines seemed to use a space?  And in the data lines, if it is just a space, then how would 2 word names be handled?  Meaning:

james 20 m london student
james smith 20 m london student


»bp
Avatar of Matty

ASKER

Please use space as a delimeter. The final output should look like
james 20 m london student
 Joan 43 f Baltimore civilEngineer
 jimmy 39 m NewYork teacher
 tanya 36 f Vegas attorney


Thanks
ASKER CERTIFIED SOLUTION
Avatar of Bill Prew
Bill Prew

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Matty

ASKER

Wow. Bill you are a life saver. Thank you so much. Thank you so very much.
Please there is one more text file that I have to deal with . This one does not have a delimeter. It just have specification of the starting and ending position  of each data element.
data_element         start End
Name                        1       5
age                            6       7
sex                            8       8
city                            9       17
profession              18     30

using same files we used before with no delimeters
 
james28mlondonstudent
Joan24fpariscivilEngineer
jimmy30mdelhiteacher
tanya36fLondonattorney

If I want to read the age  of each person . The age of James is 28 and city of london, Joan is 24 from paris, Jimmy is 30  from delhi and tanya is 36 from london.  Now the requirement is to update above  file to change their age and their city so that the end result will look like below text file after the update

james20mlondonstudent
Joan43fBaltimorecivilEngineer
jimmy39mNewYorkteacher
tanya36fVegasattorney

Bill I do understand you are taking your time to help me on this. I truly appreciate and I am very grateful.
Thanks
data_element         start End
Name                        1       5
age                            6       7
sex                            8       8
city                            9       17
profession              18     30

using same files we used before with no delimeters
 
james28mlondonstudent
Joan24fpariscivilEngineer
jimmy30mdelhiteacher
tanya36fLondonattorney

I don't think I understand.  If the text file was truly positional then every field would align with the specification you provided.  But for age for example, it seems to be in columns 6-7 sometimes, but 5-6 another time.  A similar situation exists for the other fields...


»bp
Avatar of Matty

ASKER

Sorry Bill. You are correct. Below is the file before update. I used # to indicate end of line. Please copy and paste in notepad for proper alignment

james28mlondon   student      #
Joan 24fparis    civilEngineer#
jimmy30mdelhi    teacher      #
tanya36fLondon   attorney     #.

File after update:

james20mlondon   student      #
Joan 43fBaltimorecivilEngineer#
jimmy39mNewYork  teacher      #
tanya36fVegas    attorney     #
Avatar of Matty

ASKER

I am having difficulty aligning it in this thing . Let me try again. However the whole idea is that any data that is less than specified length is padded with space to make up the length. all lines start in the first position
Avatar of Matty

ASKER

I have attached the note pad that has the spec.
Spec.txt
Is the "spec" information to be hard coded, or read from another text file?


»bp
Avatar of Matty

ASKER

It should be read from another file
Avatar of Matty

ASKER

Hi Bill,

If it is challenging to code it by reading the specification from a file, can you show me how to do it if the spec info is hard coded.

Thanks
Sorry, was away on holiday, and then took ill for a bit, I will be getting back to this...


»bp
Avatar of Matty

ASKER

Sorry to hear that you were sick. Glad that you are well now. I made a little change on the file. So please work with this attached file instead.

Thank you so much Bill
Spec.txt
Avatar of Matty

ASKER

Hi Bill,

I have solved the problem. Thank you so much for all your assistance. The foundation of the solution is based on below script that I wrote to solve the puzzle

' ========================  Search and replace any Text in a specific position of a Text FILE  
' Prerequisite for it to work. You must know the starting position of strOfInt (string of interest) and it's number of characters and
'Line number where it occurs

 ucTestsr= "End of Searchand replace Text in a FILE"
msgbox len(ucTestsr)
 Leftsr= left(ucTestsr,8-1)  ' 8 is the starting position of String of interest, 1 is a constant to make sure that the Left string function does not touch first xter of string of interest
'strOfInt = "Search"
 strOfInt = "Sea   "
 Rightstr= mid(ucTestsr,8+6)  ' 8 is the starting position of String of interest, 6 is the number of xters of string of interest
 Result = Leftsr + strOfInt + Rightstr
msgbox Result
msgbox len(Result)
Great, glad you got something that solved the new requirement.


»bp
Avatar of Matty

ASKER

Using the carriage return on line 12 of solution
arrLines = Split(strText, vbCrLf)