python string find and replace in text file - python

I'm reading a file and replacing a text string. I'm doing this for a few different strings, I know this isn't the most effeciant code I'm just trying to get it working. Here's what I have:
for line in fileinput.input(new_config, inplace=1):
print line.replace("http://domain.com", self.site_address)
print line.replace("dbname", self.db_name)
print line.replace("root", self.db_user)
print line.replace("password", self.db_pass)
print line.replace("smvc_", self.prefix
this works but it also writes every line in the file 5 times and only replaces the string on the first attempt on not on the new lines it creates (doesn't matter if it matches the string or not)

You just need to treat it as one string and apply all replacements to it.
for line in fileinput.input(new_config, inplace=1):
line = line.replace("http://domain.com", self.site_address)
line = line.replace("dbname", self.db_name)
line = line.replace("root", self.db_user)
line = line.replace("password", self.db_pass)
line = line.replace("smvc_", self.prefix)
print line
If it doesn't find any of those targets it will just not make any change to the line string so it will just replace what it DOES find.

for line in fileinput.input(new_config, inplace=1):
print line.replace(
"http://domain.com", self.site_address).replace(
"dbname", self.db_name).replace(
"root", self.db_user).replace(
"password", self.db_pass).replace("smvc_", self.prefix)
Done by copying and pasting what you wrote and using only the delete key and re-indenting. No characters added except the last closing paren.
Alternatively, this format may be clearer. It uses the backslash character to split the one line in a neater way, for better readability:
print line.replace("http://domain.com", self.site_address) \
.replace("dbname", self.db_name) \
.replace("root", self.db_user) \
.replace("password", self.db_pass) \
.replace("smvc_", self.prefix)

You can read a file line by line.
And at every line look for the word you would like to replace.
For example:
line1 = 'Hello World There'
def Dummy():
lineA = line1.replace('H', 'A')
lineB = lineA.replace('e', 'o')
print(lineB)
Dummy()
Then wirte lineB to a file.

Related

Appending string to a line read from file places appended string on next line

I have a .txt file like the following:
abc
def
ghi
Now, I want to add some string behind each row directly. However, my output is:
abc
---testdef
---testghi---test
My code is as follows:
file_read = open("test.txt", "r")
lines = file_read.readlines()
file_read.close()
new_file = open("res.txt", "w")
for line in lines:
new_file.write(line + "---test") # I tried to add "\r" in the middle of them, but this didn't work.
new_file.close()
You need to strip the new line using .rstrip():
for line in lines:
new_file.write(f"{line.rstrip()}---test\n")
Then, res.txt contains:
abc---test
def---test
ghi---test
What I understood is, you want to add a string behind a string, for example "abcd" should be changed into "---testabcd".
So the mistake you made is in new_file.write(line + "---test"), if you want add string1 before a string2, then you have to specify string1 first then string2.
So change it tonew_file.write("---test" + line)
Tip: Instead of using '+' operator, use f strings or .format.
f"---test{line}" this is f string.
"Hello {friends}".format(friends="myname")
For use of '\r':
Whenever you will use this special escape character \r, the rest of the content after the \r will come at the front of your line and will keep replacing your characters one by one until it takes all the contents left after the \r in that string.
print('Python is fun')
Output: Python is fun
Now see what happens if I use a carriage return here
print('Python is fun\r123456')
Output: 123456 is fun
So basically, it just replaces indexes of string to character after \r.

python fileinput find and replace line

I am trying to find a line starts with specific string and replace entire line with new string
I tried this code
filename = "settings.txt"
for line in fileinput.input(filename, inplace=True):
print line.replace('BASE_URI =', 'BASE_URI = "http://example.net"')
This one not replacing entire line but just a matching string. what is best way to replace entire line starting with string ?
You don't need to know what old is; just redefine the entire line:
import sys
import fileinput
for line in fileinput.input([filename], inplace=True):
if line.strip().startswith('BASE_URI ='):
line = 'BASE_URI = "http://example.net"\n'
sys.stdout.write(line)
Are you using the python 2 syntax. Since python 2 is discontinued, I will try to solve this in python 3 syntax
suppose you need to replace lines that start with "Hello" to "Not Found" then you can do is
lines = open("settings.txt").readlines()
newlines = []
for line in lines:
if not line.startswith("Hello"):
newlines.append(line)
else:
newlines.append("Not Found")
with open("settings.txt", "w+") as fh:
for line in newlines:
fh.write(line+"\n")
This should do the trick:
def replace_line(source, destination, starts_with, replacement):
# Open file path
with open(source) as s_file:
# Store all file lines in lines
lines = s_file.readlines()
# Iterate lines
for i in range(len(lines)):
# If a line starts with given string
if lines[i].startswith(starts_with):
# Replace whole line and use current line separator (last character (-1))
lines[i] = replacement + lines[-1]
# Open destination file and write modified lines list into it
with open(destination, "w") as d_file:
d_file.writelines(lines)
Call it using this parameters:
replace_line("settings.txt", "settings.txt", 'BASE_URI =', 'BASE_URI = "http://example.net"')
Cheers!

Add a character to a string

I am newbie with python and I have one problem with a small script I hope someone can give me a clue.
I have a file called "one.txt" which has the following 2 lines:
Hello
Goodbye
I want to add two characters ("/1") to the end of each line and write it in another file called result.txt:
result.txt
Hello1/
Goodbye1/
I tried the following:
x=open("one.txt","r")
y=open("result.txt","w")
for line in x:
line2= "/1" +line
y.write(line2)
and I get:
1/Hello
1/Goodbye
if I change line2 with:
line2= line + "/1"
I get:
Hello
/1Goodbye
/1
which is also not correct
any clues?
You forgot to strip the newline after reading the line and to add it back in before writing.
Here's yet another version, using context managers for the files (so you don't forget to close them later) - otherwise it's similar to the answer by #IgorPomaranskiy:
with open("one.txt") as x, open("result.txt", "w") as y:
for line in x:
y.write("{}\n".format(line.strip() + "/1"))
x = open("one.txt", "r")
y = open("result.txt", "w")
for line in x:
y.write("{}/1\n".format(line.strip())
When you read a line from a file, the string contains the newline character that indicated the end of the line. Your string isn't "Hello", it's "Hello\n". You need to remove that newline, create your output string, and add another newline when you write it back out.
for line in x:
line = line.rstrip('\n')
line2 = line + '/1\n'
y.write(line2)

How to only read a file between certain phrases

Just a basic question. I know how to read information from a file etc but how would I go about only including the lines that are in between certain lines?
Say I have this :
Information Included in file but before "beginning of text"
" Beginning of text "
information I want
" end of text "
Information included in file but after the "end of text"
Thank you for any help you can give to get me started.
You can read the file in line by line until you reach the start-markerline, then do something with the lines (print them, store them in a list, etc) until you reach the end-markerline.
with open('myfile.txt') as f:
line = f.readline()
while line != ' Beginning of text \n':
line = f.readline()
while line != ' end of text \n':
# add code to do something with the line here
line = f.readline()
Make sure to exactly match the start- and end-markerlines. In your example they have a leading and trailing blank.
Yet another way to do it, is to use two-argument version of iter():
start = '" Beginning of text "\n'
end = '" end of text "\n'
with open('myfile.txt') as f:
for line in iter(f.readline, start):
pass
for line in iter(f.readline, end):
print line
see https://docs.python.org/2/library/functions.html#iter for details
I would just read the file line by line and check each line if it matches beginning or end string. The boolean readData then indicates if you are between beginning and end and you can read the actual information to another variable.
# Open the file
f = open('myTextFile.txt')
# Read the first line
line = f.readline()
readData=false;
# If the file is not empty keep reading line one at a time
# until the file is empty
while line:
# Check if line matches beginning
if line == "Beginning of text":
readData=true;
# Check if line matches end
if line == "end of text"
readData=false;
# We are between beginning and end
if readData:
(...)
line = f.readline()
f.close()

How do I copy multiple lines?

I have the following file:
this is the first line
and this is the second line
now it is the third line
wow, the fourth line
but now it's the fifth line
etc...
etc...
etc...
Starting from "now it is the third line" to "but now it's the fifth line", how do I copy those three lines (without knowing the line numbers of those lines)? In perl, you would do something like:
/^now it is/../^but now/
What is the equivalent in python?
I have (which obviously only grabs 1 of the lines):
regex = re.compile("now it is")
for line in content:
if regex.match(line):
print line
EDIT:
reg = re.compile(r"now it is.*but now it.*", re.MULTILINE | re.DOTALL)
matches = reg.search(urllib2.urlopen(url).read())
for match in matches.group():
print match
This prints:
n
o
w
i
t
i
s
.
.
.
ie it returns characters and not the complete line
I think you just need to see re.MULTILINE flag. Thanks to it you can perform similar match and get the text that is combined from the lines you want.
EDIT:
The complete solution involves using re.MULTILINE and re.DOTALL flags, plus non-greedy regexp:
>>> text = """this is the first line
and this is the second line
now it is the third line
wow, the fourth line
but now it's the fifth line
etc...
etc...
etc..."""
>>> import re
>>> match = re.search('^(now it is.*?but now.*?)$', text, flags=re.MULTILINE|re.DOTALL)
>>> print match.group()
now it is the third line
wow, the fourth line
but now it's the fifth line
you can easily make a generator to do this
def re_range(f, re_start, re_end):
for line in f:
if re_start.match(line):
yield line
break
for line in f:
yield line
if re_end.match(line):
break
and you can call it like this
import re
re_start = re.compile("now it is")
re_end = re.compile("but now")
with open('in.txt') as f:
for line in re_range(f, re_start, re_end):
print line,
f = open("yourfile") #that is, the name of your file with extension in quotes
f = f.readlines()
Now f will be a list of each line in the file. f[0] will be the first line, f[1] the second and so on. To grab the third to fifth line you would use f[2:5]
Something like that?
import re
valid = False
for line in open("/path/to/file.txt", "r"):
if re.compile("now it is").match(line):
valid = True
if re.compile("but now").match(line):
valid = False
if valid:
print line
Like this your caching just one line at a time, contrary to using readlines() where you would cache the whole file in memory.
This is assuming the regex patterns are unique in your text block, if this is not the case please give more information regarding exactly how you match the start line and the end line.
In case you just need to check the beginning of the line for a match it's even easier:
valid = False
for line in open("/path/to/file.txt", "r"):
if line.startswith("now it is"):
valid = True
if line.startswith("but now"):
valid = False
if valid:
print line

Categories