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')
Related
How can I insert a string at the beginning of each line in a text file, I have the following code:
f = open('./ampo.txt', 'r+')
with open('./ampo.txt') as infile:
for line in infile:
f.insert(0, 'EDF ')
f.close
I get the following error:
'file' object has no attribute 'insert'
Python comes with batteries included:
import fileinput
import sys
for line in fileinput.input(['./ampo.txt'], inplace=True):
sys.stdout.write('EDF {l}'.format(l=line))
Unlike the solutions already posted, this also preserves file permissions.
You can't modify a file inplace like that. Files do not support insertion. You have to read it all in and then write it all out again.
You can do this line by line if you wish. But in that case you need to write to a temporary file and then replace the original. So, for small enough files, it is just simpler to do it in one go like this:
with open('./ampo.txt', 'r') as f:
lines = f.readlines()
lines = ['EDF '+line for line in lines]
with open('./ampo.txt', 'w') as f:
f.writelines(lines)
Here's a solution where you write to a temporary file and move it into place. You might prefer this version if the file you are rewriting is very large, since it avoids keeping the contents of the file in memory, as versions that involve .read() or .readlines() will. In addition, if there is any error in reading or writing, your original file will be safe:
from shutil import move
from tempfile import NamedTemporaryFile
filename = './ampo.txt'
tmp = NamedTemporaryFile(delete=False)
with open(filename) as finput:
with open(tmp.name, 'w') as ftmp:
for line in finput:
ftmp.write('EDF '+line)
move(tmp.name, filename)
For a file not too big:
with open('./ampo.txt', 'rb+') as f:
x = f.read()
f.seek(0,0)
f.writelines(('EDF ', x.replace('\n','\nEDF ')))
f.truncate()
Note that , IN THEORY, in THIS case (the content is augmented), the f.truncate() may be not really necessary. Because the with statement is supposed to close the file correctly, that is to say, writing an EOF (end of file ) at the end before closing.
That's what I observed on examples.
But I am prudent: I think it's better to put this instruction anyway. For when the content diminishes, the with statement doesn't write an EOF to close correctly the file less far than the preceding initial EOF, hence trailing initial characters remains in the file.
So if the with statement doens't write EOF when the content diminishes, why would it write it when the content augments ?
For a big file, to avoid to put all the content of the file in RAM at once:
import os
def addsomething(filepath, ss):
if filepath.rfind('.') > filepath.rfind(os.sep):
a,_,c = filepath.rpartition('.')
tempi = a + 'temp.' + c
else:
tempi = filepath + 'temp'
with open(filepath, 'rb') as f, open(tempi,'wb') as g:
g.writelines(ss + line for line in f)
os.remove(filepath)
os.rename(tempi,filepath)
addsomething('./ampo.txt','WZE')
f = open('./ampo.txt', 'r')
lines = map(lambda l : 'EDF ' + l, f.readlines())
f.close()
f = open('./ampo.txt', 'w')
map(lambda l : f.write(l), lines)
f.close()
I've scraped some comments from a webpage using selenium and saved them to a text file. Now I would like to perform multiple edits to the text file and save it again. I've tried to group the following into one smooth flow but I'm fairly new to python so I just couldn't get it right. Examples of what happened to me at the bottom. The only way I could get it to work is to open and close the file over and over.
These are the action I want to perform in the order the need to:
with open('results.txt', 'r') as f:
lines = f.readlines()
with open("results.txt", "w") as f:
for line in lines:
f.write(line.replace("a sample text line", ' '))
with open('results.txt', 'r') as f:
lines = f.readlines()
with open("results.txt", "w") as f:
pattern = r'\d in \d example text'
for line in lines:
f.write(re.sub(pattern, "", line))
with open('results.txt', 'r') as f:
lines = f.readlines()
with open('results.txt','w') as file:
for line in lines:
if not line.isspace():
file.write(line)
with open('results.txt', 'r') as f:
lines = f.readlines()
with open("results.txt", "w") as f:
for line in lines:
f.write(line.replace(" ", '-'))
I've tried to loop them into one but I get doubled lines, words, or extra spaces.
Any help is appreciated, thank you.
If you want to do these in one smooth pass, you better open another file to write the desired results i.e.
import re
pattern = r"\d in \d example text"
# Open your results file for reading and another one for writing
with open("results.txt", "r") as fh_in, open("output.txt", "w") as fh_out:
for line in fh_in:
# Process the line
line = line.replace("a sample text line", " ")
line = re.sub(pattern, "", line)
if line.isspace():
continue
line = line.replace(" ", "-")
# Write out
fh_out.write(line)
We process each line in order you described and the resultant line goes to output file.
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.
So the text file I have is formatted something like this:
a
b
c
I know how to strip() and rstrip() but I want to get rid of the empty lines.
I want to make it shorter like this:
a
b
c
You could remove all blank lines (lines that contain only whitespace) from stdin and/or files given at the command line using fileinput module:
#!/usr/bin/env python
import sys
import fileinput
for line in fileinput.input(inplace=True):
if line.strip(): # preserve non-blank lines
sys.stdout.write(line)
You can use regular expressions :
import re
txt = """a
b
c"""
print re.sub(r'\n+', '\n', txt) # replace one or more consecutive \n by a single one
However, lines with spaces won't be removed. A better solution is :
re.sub(r'(\n[ \t]*)+', '\n', txt)
This way, wou will also remove leading spaces.
Simply remove any line that only equals "\n":
in_filename = 'in_example.txt'
out_filename = 'out_example.txt'
with open(in_filename) as infile, open(out_filename, "w") as outfile:
for line in infile.readlines():
if line != "\n":
outfile.write(line)
If you want to simply update the same file, close and reopen it to overwrite it with the new data:
filename = 'in_example.txt'
filedata = ""
with open(filename, "r") as infile:
for line in infile.readlines():
if line != "\n":
filedata += line
with open(filename, "w") as outfile:
outfile.write(filedata)
I need to write() text at the end of every line in a text file. How do I point the cursor to the end of a specific line.
Note: seek(0,2) will put me at the end of the file, but I need the end of each line.
Appreciate the help guys - I've combined your solutions to achieve what I need:
AllLines = [ (str.rstrip('\n') + 'Val2' + "\n" ) for str in AllLines ]
I can then write AllLines to a new output file.
You need to do this in two steps. Since it's safer to create a new file, you could:
with open("input.txt") as infile, open("output.txt", "w") as outfile:
for line in infile:
outfile.write(line.rstrip("\n") + "added text\n")
new_lines = []
with open("my_file") as f:
new_lines = [line.strip("\n")+"some_ending_stuff" for line in f]
with open("my_file","w") as f:
f.write("\n".join(new_lines))
something like that should work