replacing a string in a text file - python

I wrote a script that will open my text file search for a certain word, then select the line that contains this word ans split it into three parts, then it chooses the part which is a number and add 1 to it, so every time I run the script one is added to this number. here is the script:
#!/usr/bin/env python
inputFile = open('CMakeLists.txt', 'r')
version = None
saved = ""
for line in inputFile:
if "_PATCH " in line:
print "inside: ", line
version = line
else:
saved += line
inputFile.close()
inputFile = open('CMakeLists.txt', 'w')
x = version.split('"')
print "x: ", x
a = x[0]
b = int(x[1]) + 1
c = x[2]
new_version = str(a) + '"' + str(b) + '"' + str(c)
print "new_version: ", new_version
inputFile.write(str(saved))
inputFile.write(str(new_version))
inputFile.close()
but my problem is that the new number is being written at the end of the file, I want it to stay in its original place. Any ideas ?
thanks

The problem is that you write the new version number after the original file (without the version line):
inputFile.write(str(saved))
inputFile.write(str(new_version))
You could fix it by saving the lines before and after the line that contains the version separately and then save them in the right order:
#!/usr/bin/env python
inputFile = open('CMakeLists.txt', 'r')
version = None
savedBefore = ""
savedAfter = ""
for line in inputFile:
if "_PATCH " in line:
print "inside: ", line
version = line
elif version is None:
savedBefore += line
else:
savedAfter += line
inputFile.close()
inputFile = open('CMakeLists.txt', 'w')
x = version.split('"')
print "x: ", x
a = x[0]
b = int(x[1]) + 1
c = x[2]
new_version = str(a) + '"' + str(b) + '"' + str(c)
print "new_version: ", new_version
inputFile.write(savedBefore)
inputFile.write(str(new_version))
inputFile.write(savedAfter)
inputFile.close()
Note: you might need to add some extra text with the version line to make it have the same format as the original (such as adding "_PATCH").

There is a lots to say on your code.
Your mistake is that you're writing your "saved" lines and after you are writing your modified version. Hence, this modified line will be written at the end of the file.
Moreover, I advice you to use with statements.
lines = []
with open('CmakeLists.txt', 'r') as _fd:
while True:
line = _fd.readline()
if not line:
break
if '_PATCH ' in line:
a, b, c = line.split('"')
b = int(b) + 1
line = '{} "{}" {}'.format(a, b, c)
lines.append(line)
with open('CmakeLists.txt', 'w') as _fd:
for line in lines:
_fd.write(line)
This code is untested and may contains some error... also, if your input file is huge, putting every lines in a list can be a bad idea.

#!/usr/bin/env python
inputFile = open('CMakeLists.txt', 'r')
version = None
saved = ""
for line in inputFile:
if "_PATCH " in line:
print "inside: ", line
version = line
x = version.split('"')
print "x: ", x
a = x[0]
b = int(x[1]) + 1
c = x[2]
new_version = str(a) + '"' + str(b) + '"' + str(c)
saved += new_version
else:
saved += line
inputFile.close()
inputFile = open('CMakeLists.txt', 'w')
inputFile.write(str(saved))
inputFile.close()
if a certain line is found, update its content and add to saved, once for loop ends, just write saved to file

Related

How to delete the last line of my output file?

Been trying to write my PYTHON code but it will always output the file with a blank line at the end. Is there a way to mod my code so it doesn't print out the last blank line.
def write_concordance(self, filename):
""" Write the concordance entries to the output file(filename)
See sample output files for format."""
try:
file_out = open(filename, "w")
except FileNotFoundError:
raise FileNotFoundError("File Not Found")
word_lst = self.concordance_table.get_all_keys() #gets a list of all the words
word_lst.sort() #orders it
for i in word_lst:
ln_num = self.concordance_table.get_value(i) #line number list
ln_str = "" #string that will be written to file
for c in ln_num:
ln_str += " " + str(c) #loads line numbers as a string
file_out.write(i + ":" + ln_str + "\n")
file_out.close()
Output_file
Line 13 in this picture is what I need gone
Put in a check so that the new line is not added for the last element of the list:
def write_concordance(self, filename):
""" Write the concordance entries to the output file(filename)
See sample output files for format."""
try:
file_out = open(filename, "w")
except FileNotFoundError:
raise FileNotFoundError("File Not Found")
word_lst = self.concordance_table.get_all_keys() #gets a list of all the words
word_lst.sort() #orders it
for i in word_lst:
ln_num = self.concordance_table.get_value(i) #line number list
ln_str = "" #string that will be written to file
for c in ln_num:
ln_str += " " + str(c) #loads line numbers as a string
file_out.write(i + ":" + ln_str)
if i != word_lst[-1]:
file_out.write("\n")
file_out.close()
The issue is here:
file_out.write(i + ":" + ln_str + "\n")
The \n adds a new line.
The way to fix this is to rewrite it slightly:
ln_strs = []
for i in word_lst:
ln_num = self.concordance_table.get_value(i) #line number list
ln_str = " ".join(ln_num) #string that will be written to file
ln_strs.append(f"{i} : {ln_str}")
file_out.write('\n'.join(ln_strs))
Just btw, you should actually not use file_out = open() and file_out.close() but with open() as file_out:, this way you always close the file and an exception won't leave the file hanging

How to convert multi line INI file to single line INI file in Python?

I have INI file formatted like this:
But i need it to look like this:
What would be the easiest solution to write such converter?
I tried to do it in Python, but it don't work as expected. My code is below.
def fix_INI_file(in_INI_filepath, out_INI_filepath):
count_lines = len(open( in_INI_filepath).readlines() )
print("Line count: " + str(count_lines))
in_INI_file = open(in_INI_filepath, 'rt')
out_arr = []
temp_arr = []
line_flag = 0
for i in range(count_lines):
line = in_INI_file.readline()
print (i)
if line == '':
break
if (line.startswith("[") and "]" in line) or ("REF:" in line) or (line == "\n"):
out_arr.append(line)
else:
temp_str = ""
line2 = ""
temp_str = line.strip("\n")
wh_counter = 0
while 1:
wh_counter += 1
line = in_INI_file.readline()
if (line.startswith("[") and "]" in line) or ("REF:" in line) or (line == "\n"):
line2 += line
break
count_lines -= 1
temp_str += line.strip("\n") + " ; "
temp_str += "\n"
out_arr.append(temp_str)
out_arr.append(line2 )
out_INI_file = open(out_INI_filepath, 'wt+')
strr_blob = ""
for strr in out_arr:
strr_blob += strr
out_INI_file.write(strr_blob)
out_INI_file.close()
in_INI_file.close()
Fortunately, there's a much easier way to handle this than by parsing the text by hand. The built-in configparser module supports keys without values via the allow_no_values constructor argument.
import configparser
read_config = configparser.ConfigParser(allow_no_value=True)
read_config.read_string('''
[First section]
s1value1
s1value2
[Second section]
s2value1
s2value2
''')
write_config = configparser.ConfigParser(allow_no_value=True)
for section_name in read_config.sections():
write_config[section_name] = {';'.join(read_config[section_name]): None}
with open('/tmp/test.ini', 'w') as outfile:
write_config.write(outfile)
While I don't immediately see a way to use the same ConfigParser object for reading and writing (it maintains default values for the original keys), using the second object as a writer should yield what you're looking for.
Output from the above example:
[First section]
s1value1;s1value2
[Second section]
s2value1;s2value2

ValueError: I/O operation on closed file. -- For Loop

I've seen questions like this but mine is slightly different as I don't know where to indent because I'm using a 'for' loop instead of 'with'.
f = open("Roll_List", "r+")
for myline in f:
print (myline)
if CurrentUser in myline:
x = myline.split()
print (x[1])
s = str(int(x[1]) + z)
f.write(CurrentUser + " " + s)
f.close()
Try doing f.close outside the for loop
f = open("Roll_List", "r+")
for myline in f:
print (myline)
if CurrentUser in myline:
x = myline.split()
print (x[1])
s = str(int(x[1]) + z)
f.write(CurrentUser + " " + s)
f.close()
Use a with statement to automatically close the file after you're done with it.
with open("Roll_List", "r+") as f:
for myline in f:
print(myline)
if CurrentUser in myline:
x = myline.split()
print(x[1])
s = str(int(x[1]) + z)
f.write(CurrentUser + " " + s)

Python write function output to file

I'm sorry if this is silly question but I have no much Python experience
I have function for comparing files
def compare_files(file1, file2):
fname1 = file1
fname2 = file2
# Open file for reading in text mode (default mode)
f1 = open(fname1)
f2 = open(fname2)
# Print confirmation
#print("-----------------------------------")
#print("Comparing files ", " > " + fname1, " < " +fname2, sep='\n')
#print("-----------------------------------")
# Read the first line from the files
f1_line = f1.readline()
f2_line = f2.readline()
# Initialize counter for line number
line_no = 1
# Loop if either file1 or file2 has not reached EOF
while f1_line != '' or f2_line != '':
# Strip the leading whitespaces
f1_line = f1_line.rstrip()
f2_line = f2_line.rstrip()
# Compare the lines from both file
if f1_line != f2_line:
########## If a line does not exist on file2 then mark the output with + sign
if f2_line == '' and f1_line != '':
print ("Line added:Line-%d" % line_no + "-"+ f1_line)
#otherwise output the line on file1 and mark it with > sign
elif f1_line != '':
print ("Line changed:Line-%d" % line_no + "-"+ f1_line)
########### If a line does not exist on file1 then mark the output with + sign
if f1_line == '' and f2_line != '':
print ("Line removed:Line-%d" % line_no + "-"+ f1_line)
# otherwise output the line on file2 and mark it with < sign
#elif f2_line != '':
#print("<", "Line-%d" % line_no, f2_line)
# Print a blank line
#print()
#Read the next line from the file
f1_line = f1.readline()
f2_line = f2.readline()
#Increment line counter
line_no += 1
# Close the files
f1.close()
f2.close()
I want to print function output to a text file
result=compare_files("1.txt", "2.txt")
print (result)
Line changed:Line-1-aaaaa
Line added:Line-2-sss
None
i tried following:
f = open('changes.txt', 'w')
f.write(str(result))
f.close
but only None is printed to changes.txt
I'm using "workaround" sys.stdout but wonder is there any other way instead of redirecting print output.
If in function output I specify return instead of print then I'm getting only first output line (Line changed:Line-1-aaaaa) to changes.txt
Your 'compare_files' function does not return anything and therefore nothing is written to the file. Make the function 'return' something and it should work.
Because you are not returning anything by default the function returns None so that is reflected in your changes.txt file. you can create a variable that stores the output that you wanted and returns it.
def compare_files(file1, file2):
fname1 = file1
fname2 = file2
# Open file for reading in text mode (default mode)
f1 = open(fname1)
f2 = open(fname2)
output_string = ""
# Print confirmation
# print("-----------------------------------")
# print("Comparing files ", " > " + fname1, " < " +fname2, sep='\n')
# print("-----------------------------------")
# Read the first line from the files
f1_line = f1.readline()
f2_line = f2.readline()
# Initialize counter for line number
line_no = 1
# Loop if either file1 or file2 has not reached EOF
while f1_line != '' or f2_line != '':
# Strip the leading whitespaces
f1_line = f1_line.rstrip()
f2_line = f2_line.rstrip()
# Compare the lines from both file
if f1_line != f2_line:
########## If a line does not exist on file2 then mark the output with + sign
if f2_line == '' and f1_line != '':
print("Line added:Line-%d" % line_no + "-" + f1_line)
output_string += "Line added:Line-%d" % line_no + "-" + f1_line + "\n"
# otherwise output the line on file1 and mark it with > sign
elif f1_line != '':
print("Line changed:Line-%d" % line_no + "-" + f1_line)
output_string += "Line changed:Line-%d" % line_no + "-" + f1_line +"\n"
########### If a line does not exist on file1 then mark the output with + sign
if f1_line == '' and f2_line != '':
print("Line removed:Line-%d" % line_no + "-" + f1_line)
output_string += "Line removed:Line-%d" % line_no + "-" + f1_line +"\n"
# otherwise output the line on file2 and mark it with < sign
# elif f2_line != '':
# print("<", "Line-%d" % line_no, f2_line)
# Print a blank line
# print()
# Read the next line from the file
f1_line = f1.readline()
f2_line = f2.readline()
# Increment line counter
line_no += 1
# Close the files
f1.close()
f2.close()
return output_string
Your function isn’t returning any thing so you are printing ‘None’. If you want all the print to go to a file instead of stdout like it does by default you can chane each print statement like you did to the return value.
Or you can use redirection for the whole program like done in here.
Your compare_files() just prints, but doesn't pass anything to its caller.
If you want to pass one item to the caller, you use return. The flow of your function ends there.
If you want to pass several items to the caller, you yield them. Using yield turns your function ito a generator function. Calling a generator function produces a generator object which can be iterated over.
Example:
def produce_strings():
for i in ['a', 'b', 'c']:
yield i + "x"
result = "\n".join(produce_strings())
print(result) # prints a line end separated string made of "ax", "bx" and "cx".

How do I print out to a .txt

For my code below i was wanting to print out a full sentences in which certain words from my word lists appear, aswell it would print out the word count underneath each specific word into a .txt file. I succesfully achieved this in the terminal but am really struggling to get it into a .txt. At the moment i can only seem to get it to print out the word count in the .txt but the sentences are still printing to terminal, does anybody know where i maybe going wrong? Sorry for my lack of knowledge beginner learning python. Thanks
import re, os
pathWordLists = "E:\\Python\WordLists"
searchfilesLists = os.listdir(pathWordLists)
pathWordbooks = "E:\\Python\Books"
searchfilesbooks = os.listdir(pathWordBooks)
lush = open("WorkWork.txt", "w")
def searchDocs(word):
for document in searchfilesbooks:
file = os.path.join(pathWordbooks, document)
text = open(file, "r")
hit_count = 0
for line in text:
if re.findall(word, line):
hit_count = hit_count +1
print(document + " |" + line, end="")
print(document + " => " + word + "=> "+ str(hit_count), file=lush)
text.close()
lush.flush()
return
def searchWord():
for document in searchfilesLists:
file = os.path.join(pathWordLists, document)
text = open(file, "r")
for line in text:
#print(line)
searchDocs(line.strip())
text.close()
print("Finish")
searchWord()
In case you're printing sentences with print(document + " |" + line, end="") you forgot the file parameter. Adding it should fix the problem:
print(document + " |" + line, end="", file=lush)
Try storing the result in a variable and then writing the variable to the file. Something like this:
def searchDocs(word):
results = []
for document in searchfilesbooks:
file = os.path.join(pathWordbooks, document)
with open(file, "r") as text:
lines = text.readlines()
hit_count = 0
for line in lines:
if re.findall(word, line):
hit_count += 1
results.append(document + " |" + line)
results.append(document + " => " + word + "=> "+ str(hit_count))
with open("WorkWork.txt", "w") as f:
f.write('\n'.join(results))

Categories

Resources