Reading and writing files python - python

I am trying to write three separate line in a text document based on input obtained from a dialogue window. I am sure this is a simple fix but I can't seem to write the three lines as separate lines. Would someone mind telling me what's wrong with this bit of code?
file = open('file.txt', 'wb')
file.write('input1')
file.write('input2')
file.write('input3')
The inputs should be on different lines but instead they come out as:
input1input2input3
Instead of:
input1
input2
input3

Try this:
file = open('file.txt', 'wb')
file.write('input1\n')
file.write('input2\n')
file.write('input3\n')
You are appending the newline character '\n' to advance to the next line.
If you use the with construct, it will automatically close the file for you:
with open('file.txt', 'wb') as file:
file.write('input1\n')
file.write('input2\n')
file.write('input3\n')
Also, consider using a different variable name in place of file.

Your issue is that you haven't included newlines. Remember, Python is outputting like a typewriter--you don't tell it to go to a new line, it won't. The way to write a newline is \n.
So,
file.write('\n'.join([input1, input2, input3]))
Would do it.

Related

How to alter multiple text files using a python script

I'm trying to alter multiple text files using a python scrip but I'm getting, not all, but some empty files as output. How to solve this?
def tratador_arquivo(arquivo):
with open(arquivo, 'r+',encoding="utf8") as inputtext:
for ponto in inputtext:
saida="saida_"+arquivo
with open(saida, 'w') as saidatemp:
saidatemp.write(ponto.replace('. ','.\n'))
import os
pasta = os.listdir('/Users/gabri/Desktop/Textos Imóveis')
os.chdir('/Users/gabri/Desktop/Textos Imóveis')
for arquivo in pasta:
tratador_arquivo(arquivo)
Expanding abarnert's answer, you may get the whole code as follows:
def tratador_arquivo(arquivo):
saida = "saida_" + arquivo
with open(arquivo, 'r+',encoding="utf8") as inputtext, open(saida, 'w') as saidatemp:
for ponto in inputtext:
saidatemp.write(ponto.replace('. ', '.\n'))
Also mind the indentation error of the function content in the code you provided.
Look at your loop:
for ponto in inputtext:
saida="saida_"+arquivo
with open(saida, 'w') as saidatemp:
saidatemp.write(ponto.replace('. ','.\n'))
This re-opens the same file over and over, once for each line of the input file. Since you open it in w mode, that truncates the file, erasing whatever you'd previously written there, and replaces it with just the (transformed) newest line. So, at the end of the loop, your output file only has the (transformed) last line of the input file.
This is probably always wrong (although it's hard to say that for sure when I don't know what exactly you're trying to do). But in cases where the input file ends with a blank line, it will be especially obvious that it's wrong, because the only thing in the output file will be that blank line.
What you probably want to do is this:
saida="saida_"+arquivo
with open(saida, 'w') as saidatemp:
for ponto in inputtext:
saidatemp.write(ponto.replace('. ','.\n'))
In other words, just open the file once, and keep writing new lines to it.

Automate notepad++ editing csv file using script

So I have this code that generates a .csv file of data, however the formatting is off due to the escapechar (can't fix this). I need to make all the double spaces into single spaces. I can do this in notepad++ with replace all, so I've written a python script using a notepad++ plugin that does this. Now I'd like to automate opening the file and running the script; is this possible using a batch file? Is there a better way to do this?
Example of before and after format needed:
"_time","location"
"2018-04-03T08:32:45.565000-0400","(0 , 3)"
"2018-04-03T08:32:45.565000-0400","(2 , 5)"
"_time","location"
"2018-04-03T08:32:45.565000-0400","(0,3)"
"2018-04-03T08:32:45.565000-0400","(2,5)"
You can do it all with Python.
Just read the file and use the string replace method. Probably you will create a temporary file with the adjustments and then rename it. Something like:
with open(fname) as f:
lines = f.readlines()
for line in lines:
newline = line.replace(" ", " ") #two spaces become one space
#... write newline to temp file, etc.

Replace string in specific line of nonstandard text file

Similar to posting: Replace string in a specific line using python, however results were not forethcomming in my slightly different instance.
I working with python 3 on windows 7. I am attempting to batch edit some files in a directory. They are basically text files with .LIC tag. I'm not sure if that is relevant to my issue here. I am able to read the file into python without issue.
My aim is to replace a specific string on a specific line in this file.
import os
import re
groupname = 'Oldtext'
aliasname = 'Newtext'
with open('filename') as f:
data = f.readlines()
data[1] = re.sub(groupname,aliasname, data[1])
f.writelines(data[1])
print(data[1])
print('done')
When running the above code I get an UnsupportedOperation: not writable. I am having some issue writing the changes back to the file. Based on suggestion of other posts, I edited added the w option to the open('filename', "w") function. This causes all text in the file to be deleted.
Based on suggestion, the r+ option was tried. This leads to successful editing of the file, however, instead of editing the correct line, the edited line is appended to the end of the file, leaving the original intact.
Writing a changed line into the middle of a text file is not going to work unless it's exactly the same length as the original - which is the case in your example, but you've got some obvious placeholder text there so I have no idea if the same is true of your actual application code. Here's an approach that doesn't make any such assumption:
with open('filename', 'r') as f:
data = f.readlines()
data[1] = re.sub(groupname,aliasname, data[1])
with open('filename', 'w') as f:
f.writelines(data)
EDIT: If you really wanted to write only the single line back into the file, you'd need to use f.tell() BEFORE reading the line, to remember its position within the file, and then f.seek() to go back to that position before writing.

In place replacement of text in a file in Python

I am using the following code to upload a file on server using FTP after editing it:
import fileinput
file = open('example.php','rb+')
for line in fileinput.input('example.php'):
if 'Original' in line :
file.write( line.replace('Original', 'Replacement'))
file.close()
There is one thing, instead of replacing the text in its original place, the code adds the replaced text at the end and the text in original place is unchanged.
Also, instead of just the replaced text, it prints out the whole line. Could anyone please tell me how to resolve these two errors?
1) The code adds the replaced text at the end and the text in original place is unchanged.
You can't replace in the body of the file because you're opening it with the + signal. This way it'll append to the end of the file.
file = open('example.php','rb+')
But this only works if you want to append to the end of the document.
To bypass this you may use seek() to navigate to the specific line and replace it. Or create 2 files: an input_file and an output_file.
2) Also, instead of just the replaced text, it prints out the whole line.
It's because you're using:
file.write( line.replace('Original', 'Replacement'))
Free Code:
I've segregated into 2 files, an inputfile and an outputfile.
First it'll open the ifile and save all lines in a list called lines.
Second, it'll read all these lines, and if 'Original' is present, it'll replace it.
After replacement, it'll save into ofile.
ifile = 'example.php'
ofile = 'example_edited.php'
with open(ifile, 'rb') as f:
lines = f.readlines()
with open(ofile, 'wb') as g:
for line in lines:
if 'Original' in line:
g.write(line.replace('Original', 'Replacement'))
Then if you want to, you may os.remove() the non-edited file with:
More Info: Tutorials Point: Python Files I/O
The second error is how the replace() method works.
It returns the entire input string, with only the specified substring replaced. See example here.
To write to a specific place in the file, you should seek() to the right position first.
I think this issue has been asked before in several places, I would do a quick search of StackOverflow.
Maybe this would help?
Replacing stuff in a file only works well if original and replacement have the same size (in bytes) then you can do
with open('example.php','rb+') as f:
pos=f.tell()
line=f.readline()
if b'Original' in line:
f.seek(pos)
f.write(line.replace(b'Original',b'Replacement'))
(In this case b'Original' and b'Replacement' do not have the same size so your file will look funny after this)
Edit:
If original and replacement are not the same size, there are different possibilities like adding bytes to fill the hole or moving everything after the line.

How to write a list to a file with newlines in Python3

I'm trying to write an array (list?) to a text file using Python 3. Currently I have:
def save_to_file(*text):
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
for lines in text:
print(lines, file = myfile)
myfile.close
This writes what looks like the array straight to the text file, i.e.,
['element1', 'element2', 'element3']
username#machine:/path$
What I'm looking to do is create the file with
element1
element2
element3
username#machine:/path$
I've tried different ways to loop through and append a "\n" but it seems that the write is dumping the array in one operation. The question is similar to How to write list of strings to file, adding newlines? but the syntax looked like it was for Python 2? When I tried a modified version of it:
def save_to_file(*text):
myfile = open('/path/to/filename.txt', mode='wt', encoding='utf-8')
for lines in text:
myfile.write(lines)
myfile.close
...the Python shell gives "TypeError: must be str, not list" which I think is because of changes between Python2 and Python 3. What am I missing to get each element on a newline?
EDIT: Thank you to #agf and #arafangion; combining what both of you wrote, I came up with:
def save_to_file(text):
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
myfile.write('\n'.join(text))
myfile.write('\n')
It looks like I had part of the issue with "*text" (I had read that expands arguments but it didn't click until you wrote that [element] was becoming [[element]] that I was getting a str-not-list type error; I kept thinking I needed to tell the definition that it was getting a list/array passed to it and that just stating "test" would be a string.) It worked once I changed it to just text and used myfile.write with join, and the additional \n puts in the final newline at the end of the file.
myfile.close -- get rid of that where you use with. with automatically closes myfile, and you have to call close like close() anyway for it to do anything when you're not using with. You should just always use with on Python 3.
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
myfile.write('\n'.join(lines))
Don't use print to write to files -- use file.write. In this case, you want to write some lines with line breaks in between, so you can just join the lines with '\n'.join(lines) and write the string that is created directly to the file.
If the elements of lines aren't strings, try:
myfile.write('\n'.join(str(line) for line in lines))
to convert them first.
Your second version doesn't work for a different reason. If you pass
['element1', 'element2', 'element3']
to
def save_to_file(*text):
it will become
[['element1', 'element2', 'element3']]
because the * puts each argument it gets into a list, even if what you pass is already a list.
If you want to support passing multiple lists, and still write them one after another, do
def save_to_file(*text):
with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
for lines in text:
myfile.write('\n'.join(str(line) for line in lines))
myfile.write('\n')
or, for just one list, get rid of the * and do what I did above.
Edit: #Arafangion is right, you should probably just use b instead of t for writing to your files. That way, you don't have to worry about the different ways different platforms handle newlines.
There are numerous mistakes there.
Your indentation is messed up.
The 'text' attribute in save_to_file refers to ALL the arguments, not just the specific argument.
You're using "text mode", which is also confusing. Use binary mode instead, so that you have a consistent and defined meaning for '\n'.
When you iterate over the 'lines in text', because of these mistakes, what you're really doing is iterating over your arguments in the function, because 'text' represents all your arguments. That is what '*' does. (At least, in this situation. Strictly speaking, it iterates over all the remaining arguments - please read the documentation).

Categories