if data.find('!masters') != -1:
f = open('masters.txt')
lines = f.readline()
for line in lines:
print lines
sck.send('PRIVMSG ' + chan + " " + str(lines) + '\r\n')
f.close()
masters.txt has a list of nicknames, how can I print every line from the file at once?. The code I have only prints the first nickname. Your help will be appreciate it. Thanks.
Firstly, as #l33tnerd said, f.close should be outside the for loop.
Secondly, you are only calling readline once, before the loop. That only reads the first line. The trick is that in Python, files act as iterators, so you can iterate over the file without having to call any methods on it, and that will give you one line per iteration:
if data.find('!masters') != -1:
f = open('masters.txt')
for line in f:
print line,
sck.send('PRIVMSG ' + chan + " " + line)
f.close()
Finally, you were referring to the variable lines inside the loop; I assume you meant to refer to line.
Edit: Oh and you need to indent the contents of the if statement.
You probably want something like:
if data.find('!masters') != -1:
f = open('masters.txt')
lines = f.read().splitlines()
f.close()
for line in lines:
print line
sck.send('PRIVMSG ' + chan + " " + str(line) + '\r\n')
Don't close it every iteration of the loop and print line instead of lines. Also use readlines to get all the lines.
EDIT removed my other answer - the other one in this discussion is a better alternative than what I had, so there's no reason to copy it.
Also stripped off the \n with read().splitlines()
You could try this. It doesn't read all of f into memory at once (using the file object's iterator) and it closes the file when the code leaves the with block.
if data.find('!masters') != -1:
with open('masters.txt', 'r') as f:
for line in f:
print line
sck.send('PRIVMSG ' + chan + " " + line + '\r\n')
If you're using an older version of python (pre 2.6) you'll have to have
from __future__ import with_statement
Loop through the file.
f = open("masters.txt")
lines = f.readlines()
for line in lines:
print line
Did you try
for line in open("masters", "r").readlines(): print line
?
readline()
only reads "a line", on the other hand
readlines()
reads whole lines and gives you a list of all lines.
Related
I'm very new to Python, and attempt to do the following
read file,
replace spaces with new lines,
remove any line containing the ":" character
write result to text file
So far I have got the following, I know there should be a o.write somewhere, however I've tried a bunch of different spots and nothing seems to work, I'm pretty sure I'm missing something simple.
import os
i = open("input.txt", "r+")
o = open("output.txt", "a+")
for line in i.readlines():
(line.replace(" ", "\n"))
if ":" in line:
(line)
i.close()
o.close()
The input file is as follows
192.168.1.1 192.168.2.1 192.168.3.1 2001:0db8:85a3:0000:0000:8a2e:0370:7334
So I have:
EDITED to remove lines with a :
test.txt
192.168.1.1 192.168.2.1 192.168.3.1 2001:0db8:85a3:0000:0000:8a2e:0370:7334
answer.py
with open('test.txt', 'r') as f:
text = f.read()
lines = text.split(' ')
lines = [line for line in lines if ':' not in line]
with open('result.txt', 'w') as f:
f.write('\n'.join(lines))
result.txt
192.168.1.1
192.168.2.1
192.168.3.1
Is that what you wanted?
you can build your new file contents first and afterward write to it:
import os
i = open("in", "r+")
o = open("out", "a+")
result = ""
for line in i.readlines():
if ":" not in line:
result += line.replace(" ", "\n")
o.write(result)
i.close()
o.close()
Replaces the spaces with newlines before iterating over the file's contents. if you don't, then you'll only be iterating over a single line.
There's no need for the os library in your code.
Call o.write(line) after testing if the line has no colon(:).
Use the context manger to do your I/O operations.
Use more descriptive names than i and o to avoid writing confusing code.
With the above modifications, your code becomes:
with open("input.txt", "r+") as infile, open("output.txt", "a+") as outfile:
contents = infile.read().replace(' ', '\n')
for line in contents.split('\n'):
if ':' not in line:
outfile.write(line + '\n')
This question already has answers here:
Search and replace a line in a file in Python
(13 answers)
Closed 5 years ago.
I have a text file. I would like to use python v3.6 to read the text file line by line, append each line with a sub-string and replace the existing line with the appended string line by line.
To be clearer, here is the original text file;
1,2,3
4,5,6
The desired output text file should look like this;
appended_text,1,2,3
appended_text,4,5,6
This is how my code looks like;
with open(filename, 'r+') as myfile:
for line in myfile:
newline = "appended_text" + "," + line
myfile.write(newline)
I did not get what I want. What I got instead was a huge line of text appended at the end of the file. How should the code be modified? Is there a better way to implement what I want?
There's no such thing as "replacing an existing line" in a file. For what you want to do, you have to write a new file with the modified content and then replace the old file with the new one. Example code:
with open("old.file") as old, open("new.file", "w") as new:
for line in old:
line = modify(line.lstrip())
new.write(line + "\n")
os.rename("new.file", "old.file")
You cannot, in general, modify a file in place like this. Instead, write a copy to a new file, then replace the original with the new one.
with open(filename, 'r') as myfile:
with open("copy", 'w') as newfile:
for line in myfile:
newline = "appended_text" + "," + line
newfile.write(newline)
os.rename("copy", filename)
If you want to write it to the same file:
f = open(filename, 'r')
lines = f.readlines()
f.close()
lines = ['appended_text, ' + l for l in lines]
f = open(filename, 'w')
f.writelines(lines)
f.close()
Here is what I would do:
with open(filename, 'r+') as f:
lines = []
for line in f:
lines.append("appended_text" + "," + line)
f.seek(0)
for line in lines:
f.write(line)
For example:
sample.txt before:
hello
there
world
code:
fp = r"C:\Users\Me\Desktop\sample.txt"
with open(fp, 'r+') as f:
lines = []
for line in f:
lines.append("something," + line)
lines.append(line.strip() + ",something\n")
f.seek(0)
for line in lines:
f.write(line)
sample.txt after:
something,hello
hello,something
something,there
there,something
something,world
world,something
A couple of notes:
This assumes you are going to append to the front of each line. Thus the newline ('\n') is kept with the original content of each line. If you are appending to the end, I would change to: lines.append(line.strip() + "," + "appended_text").
You can probably combine "appended_text" and the "," to "appended_text,". Unless "appended_text" is a varable like appended_text = "something".
Though contextually correct as a solution to your question; I'd look to writing a new file with the changes desired and replacing the old one with the new one as recommend in other answers.
I believe to get what you want you need to put myfile.readlines() before your for loop.
The output from my print statements outputs the correct lines of data, the output file however only contains the last lines for the 3 if statements. I have tried varying the identation but this seems to only affect the code negatively.
import sys
import tokenize
file = []
f = open('Database.txt') # Opening File
for line in f:
file.append(line) # Reading in File
f.close() # Closing File
f = open('output.txt', 'w')
for line in file: # Printing out File
#print line
tokens = line.split() # splits lines along white-space (tokenise)
#print tokens
desired = '{0:<5}'.format(tokens[0])
#print desired
lined = line.split('|') # lhs is original line
if 'Not present in Line' in line:
line1 = desired + ':' + lined[1]
#print line1
if 'Not present in TV' in line:
#print line
line2 = desired + ' : ' + ' sticking ' + ' Returning ' + '\n'
#print line2
if 'Not present in Line' not in line and 'Not present in TV' not in line:
#print line
line3 = desired + ':' + lined[1]
#print line3
f.write(line1 + line2 + line3)
f.close()
You need to indent the line
f.write(line1 + line2 + line3)
to the same level as the if statements before. Currently, it's outside the for loop and is therefore executed only after that loop has ended.
Also, you may want to add a newline character after each line:
f.write(line1 + line2 + line3 + "\n")
As Jon Clements has noted correctly, you need to think about what should happen if not all three if conditions are met - in that case, lineN variables may be undefined or may still be defined with the value from the previous iteration. In fact, it's impossible for all three conditions to be met at the same time, so you'll always encounter a NameError during the very first iteration.
Only you can decide if it makes sense to set them to a default value at the start of the for loop or to do something else.
I am trying to replace a line in a file, with a string whose length differs based on the input.
If the length of string is equal to or greater than the line to be replaced,
then the file is overwritten correctly. Whereas, if the string is shorter than the line to be replaced,
then after replacing, part of the line will be appended at the end.
The code snippet used for writing to the file is given below.
replace_value = status
lines = []
filename = open(os.path.join(dst_path, asilSafety_path),'r+')
for line in filename.readlines():
line.strip('\n')
if line.startswith('export SAFETY_SRV_MODE'):
bits = line.split('=')
config, value = bits
src = config + '=' + value.strip('\n')
target = config + '= ' + replace_value
break
filename.seek(0)
for line in filename.readlines():
line = line.replace(src,target)
lines.append(line)
filename.seek(0)
for line in lines:
filename.write(line)
filename.close()
I am passing the file path and the string to be written as arguments to the function i.e., safety_configuration(dst_path, status). The variable 'replace_value' has the string to be replaced with.
Can someone please tell me, wat am i doing wrong? Or is there any other way to implement this?
import fileinput
import sys
count = 0
replace_value = status
for line in fileinput.input(["a.txt"], inplace=True, backup='.bak'):
if line.startswith('export SAFETY_SRV_MODE'):
bits = line.split('=')
config, value = bits
src = config + '=' + value.strip('\n')
target = config + '= ' + replace_value+"\n"
sys.stdout.write(line.replace(src,target))
else:
sys.stdout.write(line)
You can use file input for this instead of moving up and down the file you can change it at the time when you found it
I'd suggest looping over the lines in the file once, and if they don't match what you want to replace, simply append them to lines.
If they do, modify that line before appending it to lines. The simply re-write them out to the file.
replace_value = status
lines = []
with open(os.path.join(dst_path, asilSafety_path)) as f:
for line in f:
if line.startswith('export SAFETY_SRV_MODE'):
config, value = line.split('=')
lines.append(config + '= ' + replace_value + '\n')
else:
lines.append(line)
with open(os.path.join(dst_path, asilSafety_path), 'w') as f:
f.writelines(lines)
Your solution is correct provide you have enough memory to load whole file. You simply forgot to truncate the file object, and that's the reason why you see garbage at the end.
The last part of your script should be :
filename.seek(0)
for line in lines:
filename.write(line)
filename.truncate()
filename.close()
You can also truncate immediately after the seek.
I am reading a text file and searching data line by line, based on some condition, changing some values in the line and writing it back into another file. The new file should not contain the old Line. I have tried the following, but it did not work. I think I am missing a very basic thing.
Solution: In C++ we can increment line but in Python I am not sure how to achieve this. So as of now, I am writing old line than new line. But in the new file, I want only the new line.
Example:
M0 38 A 19 40 DATA2 L=4e-08 W=3e-07 nf=1 m=1 $X=170 $Y=140 $D=8
M0 VBN A 19 40 TEMP2 L=4e-08 W=3e-07 nf=1 m=1 $X=170 $Y=140 $D=8
The code which i tried is the following:
def parsefile():
fp = open("File1", "rb+")
update_file = "File1" + "_update"
fp_latest = open(update_file, "wb+")
for line in fp:
if line.find("DATA1") == -1:
fp_latest.write(line)
if line.find("DATA1") != -1:
line = line.split()
pin_name = find_pin_order(line[1])
update_line = "DATA " + line[1] + " " + pin_name
fp_latest.write(update_line)
line = ''.join(line)
if line.find("DATA2") != -1:
line_data = line.split()
line_data[1] = "TEMP2"
line_data =' '.join(line_data)
fp_latest.write(line_data)
if line.find("DATA3") != -1:
line_data = line.split()
line_data[1] = "TEMP3"
line_data =' '.join(line_data)
fp_latest.write(line_data)
fp_latest.close()
fp.close()
The main problem with your current code is that your first if block, which checks for "DATA1" and writes the line out if it is not found runs when "DATA2" or "DATA3" is present. Since those have their own blocks, the line ends up being duplicated in two different forms.
Here's a minimal modification of your loop that should work:
for line in fp:
if line.find("DATA1") != -1:
data = line.split()
pin_name = find_pin_order(data[1])
line = "DATA " + data[1] + " " + pin_name
if line.find("DATA2") != -1:
data = line.split()
data[1] = "TEMP2"
line =' '.join(data)
if line.find("DATA3") != -1:
data = line.split()
data[1] = "TEMP3"
line =' '.join(data)
fp_latest.write(line)
This ensures that only one line is written because there's only a single write() call in the code. The special cases simply modify the line that is to be written. I'm not sure I understand the modifications you want to have done in those cases, so there may be more bugs there.
One thing that might help would be to make the second and third if statements into elif statements instead. This would ensure that only one of them would be run (though if you know your file will never have multiple DATA entries on a single line, this may not be necessary).
If you want to write a new line in a file replacing the old content that has been readed last time, you can use the file.seek() method for moving arround the file, there is an example.
with open("myFile.txt", "r+") as f:
offset = 0
lines = f.readlines()
for oldLine in lines:
... calculate the new line value ...
f.seek(offset)
f.write(newLine)
offset += len(newLine)
f.seek(offset)