Replace last character in text file (python) - python

I have three short JSON text files. I want to combine them with Python, and as far as it works and creates an output file with everything on the right place, on the last line I have a comma, and I would like to replace it with } . I have came up with such a code:
def join_json_file (file_name_list,output_file_name):
with open(output_file_name,"w") as file_out:
file_out.write('{')
for filename in file_name_list:
with open(filename) as infile:
file_out.write(infile.read()[1:-1] + ",")
with open(output_file_name,"r") as file_out:
lines = file_out.readlines()
print lines[-1]
lines[-1] = lines[-1].replace(",","")
but it doesn't replace the last line. Could somebody help me? I am new to Python and I can't find the solution by myself.

You are writing all of the files, and then loading it back in to change the last line. The change though will only be in memory, not in the file itself. The better approach would be to avoid writing the extra , in the first place. For example:
def join_json_file (file_name_list, output_file_name):
with open(output_file_name, "w") as file_out:
file_out.write('{')
for filename in file_name_list[:-1]:
with open(filename) as infile:
file_out.write(infile.read()[1:-1] + ",")
with open(file_name_list[-1]) as infile:
file_out.write(infile.read()[1:-1])
This first writes all but the last file with the extra comma, and then writes the last file seperately. You might also want to check for the case of a single file.

Related

write output from print to a file in python

I have a code that reads multiple text files and print the last line.
from glob import glob
text_files = glob('C:/Input/*.txt')
for file_name in text_files:
with open(file_name, 'r+') as f:
lines = f.read().splitlines()
last_line = lines[-3]
print (last_line)
I want to redirect the print to an output txt file , so that i will check the sentence . Also the txt files has multiple lines of space . I want to delete all the empty lines and get the last line of the file to an output file. When i try to write it is writing only the last read file. Not all files last line is written .
Can someone help ?
Thanks,
Aarush
I think you have two separate questions.
Next time you use stack overflow, if you have multiple questions, please post them separately.
Question 1
How do I re-direct the output from the print function to a file?
For example, consider a hello world program:
print("hello world")
How do we create a file (named something like text_file.txt) in the current working directory, and output the print statements to that file?
ANSWER 1
Writing output from the print function to a file is simple to do:
with open ('test_file.txt', 'w') as out_file:
print("hello world", file=out_file)
Note that print function accepts a special keyword-argument named "file"
You must write file=f in order to pass f as input to the print function.
QUESTION 2
How do I get the last non-blank line from s file? I have an input file which has lots of line-feeds, carriage-returns, and space characters at the end of. We need to ignore blank lines, and retrieve the last lien of the file which contains at least one character which is not a white-space character.
Answer 2
def get_last_line(file_stream):
for line in map(str, reversed(iter(file_stream))):
# `strip()` removes all leading a trailing white-space characters
# `strip()` removes `\n`, `\r`, `\t`, space chars, etc...
line = line.strip()
if len(line) > 0:
return line
# if the file contains nothing but blank lines
# return the empty string
return ""
You can process multiple files like so:
file_names = ["input_1.txt", "input_2.txt", "input_3.txt"]
with open ('out_file.txt', 'w') as out_file:
for file_name in file_names:
with open(file_name, 'r') as read_file:
last_line = get_last_line(read_file)
print (last_line, file=out_file)
Instead of just print, do something like this:
print(last_line)
with open('output.txt', 'w') as fout:
fout.write(last_line)
Or you could also append to the file!

Python: Write when reading a file

I have a file in which each line contains a sentence. Some sentences are however empty, i.e. in this case there is just "\n" newline character on the line.
What I want to do is: if I find an empty sentence, I want to replace it with some symbol like .
If I replace "\n", it will be replaced at all places in the file.
However, I am not sure how to do this:
import sys
f = open(sys.argv[1], "wr")
for line in f:
if len(line.strip())==0:
line.replace("\n", "empty")
# Then write the line back on the file
f.write(line + "\n") # Will this replace the line in the file?
Is the above code correct? Can I simultaneously read the line and edit it too?
This is a quick way of solving the problem, but not the ideal way of doing it should you have memory constrictions.
f = open(sys.argv[1], "r")
lines = f.readlines()
f.close()
lines = ['empty' if i == '\n' else i for i in lines]
f = open(sys.argv[1], "w")
f.writelines(lines)
f.close()
Should you have memory restrictions, creating a function utilising yield would be the best way to go about this
Edit: I should also say unless there has been an update, I don't believe it is possible to overwrite a specific line in a file using python without re-writing the entire file.

Script not writing to file

I would like to make it so that it opens up alan.txt, search the text for all instance of scholary_tehologian and if found, add the word "test" under it. when I tried doing it this way:
## Script
with open('alan.txt', 'r+') as f:
for line in f:
if "scholarly_theologian" in line:
f.write("test")
it wouldn't write anything. I'm in Windows 8.1
You can't modify a file like this. You can only append to it, write characters instead of others, or rewrite it entirely. See How do I modify a text file in Python?.
What you should do is create another file with the content you want.
EDIT:
Claudio's answer has the code for what I offered. It has the benefit (over manicphase's code) of not keeping the whole file in memory. This is important if the file is long. manicphase's answer, on the other hand, has the benefit of not creating a second file. It rewrites the original one. Choose the one that fits your needs.
Rewritten answer because the last one was wrong.
If you want to read lines you have to put .readlines() after open(...) or f. Then there's a few ways you could insert "test".
## Script
with open('alan.txt', 'r') as f:
lines = f.readlines()
for i in range(len(lines)):
if "scholarly_theologian" in lines[i]:
lines[i] = lines[i] + "\ntest"
with open('alan.txt', 'w') as f:
f.write("\n".join(lines))
This should do the trick:
with open('output.txt', 'w') as o:
with open('alan.txt', 'r') as f:
for line in f:
o.write(line)
if line.find('scholarly_theoligian'):
o.write('test')
Like Ella Shar mentioned, you need to create a new file and add the new content into it.
If working with two files is not acceptable, the next step would be to delete the input file, and to rename the output file.

Edit and save file

I need to edit my file and save it so that I can use it for another program . First I need to put "," in between every word and add a word at the end of every line.
In order to put "," in between every word , I used this command
for line in open('myfile','r+') :
for word in line.split():
new = ",".join(map(str,word))
print new
I'm not too sure how to overwrite the original file or maybe create a new output file for the edited version . I tried something like this
with open('myfile','r+') as f:
for line in f:
for word in line.split():
new = ",".join(map(str,word))
f.write(new)
The output is not what i wanted (different from the print new) .
Second, I need to add a word at the end of every line. So, i tried this
source = open('myfile','r')
output = open('out','a')
output.write(source.read().replace("\n", "yes\n"))
The code to add new word works perfectly. But I was thinking there should be an easier way to open a file , do two editing in one go and save it. But I'm not too sure how. Ive spent a tremendous amount of time to figure out how to overwrite the file and it's about time I seek for help
Here you go:
source = open('myfile', 'r')
output = open('out','w')
output.write('yes\n'.join(','.join(line.split()) for line in source.read().split('\n')))
One-liner:
open('out', 'w').write('yes\n'.join(','.join(line.split() for line in open('myfile', 'r').read().split('\n')))
Or more legibly:
source = open('myfile', 'r')
processed_lines = []
for line in source:
line = ','.join(line.split()).replace('\n', 'yes\n')
processed_lines.append(line)
output = open('out', 'w')
output.write(''.join(processed_lines))
EDIT
Apparently I misread everything, lol.
#It looks like you are writing the word yes to all of the lines, then spliting
#each word into letters and listing those word's letters on their own line?
source = open('myfile','r')
output = open('out','w')
for line in source:
for word in line.split():
new = ",".join(word)
print >>output, new
print >>output, 'y,e,s'
How big is this file?
Maybe You could create a temporary list which would just contain everything from file you want to edit. Every element could represent one line.
Editing list of strings is pretty simple.
After Your changes you can just open Your file again with
writable = open('configuration', 'w')
and then put changed lines to file with
file.write(writable, currentLine + '\n')
.
Hope that helps - even a little bit. ;)
For the first problem, you could read all the lines in f before overwriting f, assuming f is opened in 'r+' mode. Append all the results into a string, then execute:
f.seek(0) # reset file pointer back to start of file
f.write(new) # new should contain all concatenated lines
f.truncate() # get rid of any extra stuff from the old file
f.close()
For the second problem, the solution is similar: Read the entire file, make your edits, call f.seek(0), write the contents, f.truncate() and f.close().

How to delete parts of a file in python?

I have a file named a.txt which looks like this:
I'm the first line
I'm the second line.
There may be more lines here.
I'm below an empty line.
I'm a line.
More lines here.
Now, I want to remove the contents above the empty line(including the empty line itself).
How could I do this in a Pythonic way?
Basically you can't delete stuff from the beginning of a file, so you will have to write to a new file.
I think the pythonic way looks like this:
# get a iterator over the lines in the file:
with open("input.txt", 'rt') as lines:
# while the line is not empty drop it
for line in lines:
if not line.strip():
break
# now lines is at the point after the first paragraph
# so write out everything from here
with open("output.txt", 'wt') as out:
out.writelines(lines)
Here are some simpler versions of this, without with for older Python versions:
lines = open("input.txt", 'rt')
for line in lines:
if not line.strip():
break
open("output.txt", 'wt').writelines(lines)
and a very straight forward version that simply splits the file at the empty line:
# first, read everything from the old file
text = open("input.txt", 'rt').read()
# split it at the first empty line ("\n\n")
first, rest = text.split('\n\n',1)
# make a new file and write the rest
open("output.txt", 'wt').write(rest)
Note that this can be pretty fragile, for example windows often uses \r\n as a single linebreak, so a empty line would be \r\n\r\n instead. But often you know the format of the file uses one kind of linebreaks only, so this could be fine.
Naive approach by iterating over the lines in the file one by one top to bottom:
#!/usr/bin/env python
with open("4692065.txt", 'r') as src, open("4692065.cut.txt", "w") as dest:
keep = False
for line in src:
if keep: dest.write(line)
if line.strip() == '': keep = True
The fileinput module (from the standard library) is convenient for this kind of thing. It sets things up so you can act as though your are editing the file "in-place":
import fileinput
import sys
fileobj=iter(fileinput.input(['a.txt'], inplace=True))
# iterate through the file until you find an empty line.
for line in fileobj:
if not line.strip():
break
# Iterators (like `fileobj`) pick up where they left off.
# Starting a new for-loop saves you one `if` statement and boolean variable.
for line in fileobj:
sys.stdout.write(line)
Any idea how big the file is going to be?
You could read the file into memory:
f = open('your_file', 'r')
lines = f.readlines()
which will read the file line by line and store those lines in a list (lines).
Then, close the file and reopen with 'w':
f.close()
f = open('your_file', 'w')
for line in lines:
if your_if_here:
f.write(line)
This will overwrite the current file. Then you can pick and choose which lines from the list you want to write back in. Probably not a very good idea if the file gets to large though, since the entire file has to reside in memory. But, it doesn't require that you create a second file to dump your output.
from itertools import dropwhile, islice
def content_after_emptyline(file_object):
return islice(dropwhile(lambda line: line.strip(), file_object), 1, None)
with open("filename") as f:
for line in content_after_emptyline(f):
print line,
You could do a little something like this:
with open('a.txt', 'r') as file:
lines = file.readlines()
blank_line = lines.index('\n')
lines = lines[blank_line+1:] #\n is the index of the blank line
with open('a.txt', 'w') as file:
file.write('\n'.join(lines))
and that makes the job much simpler.

Categories