I want to open an existing txt file and search for line of text appearing many times and in different places. Each time search found, insert 2 new rows below it with specified text.
I tried this code but got 'AttributeError' on 'Path.write' line ('str' object has no attribute 'write').
Path = '...\\Test.txt'
searchString = '* Start *'
with open(Path, 'r+') as f:
content = f.readlines()
nextLine = False
for line in content:
if searchString in line:
nextLine = not nextLine
else:
if nextLine:
Path.write('Name\nDirection')
nextLine = not nextLine
else:
pass
I must also allocate to 'Direction' line a number, starting at 0 and increment by 15 until all file is read. So after first instance is found, two lines are inserted into existing txt file like this;
...some text in the existing text file....
* Start *
Name
Direction 0
0 then changes to 15 on next instance (ie Direction 15), then 30 (ie Direction 30) etc until end of file.
EDITED CODE: Simplified coded. Anyone vote me up I'd appreciate
Path = '...\\Test.txt'
direction_number = 0
#Open new file
Newfile = open(Path, 'w')
#read other file
with open(Path, 'r') as f:
content = f.readlines()
#if find special text, write other lines to new file
for line in content:
Newfile.write(line)
if searchString in line:
Newfile.write('Name\nDirection %d' % direction_number)
direction_number += 15
Newfile.close()
Instead of trying to reopen and insert lines into the original file, you should just write a new file. So for each line in the old file, write it to the new file, and write the two additional lines if it contains the text in question.
direction_number = 0
with open("newfile.txt", 'w') as g:
# Loop through every line of text we've already read from
# the first file.
for line in content:
# Write the line to the new file
g.write(line)
# Also, check if the line contains the <searchString> string.
# If it does, write the "Name" and "Direction [whatever]" line.
if searchString in line:
g.write('Name\nDirection %d\n' % direction_number)
direction_number += 15
EDIT: To explain more about this second with open statement: Remember earlier that you used with open(Path, 'r+') as f: to READ your file.
The Path part is where the name of the file is stored, the r+ part means that you're opening it for reading, and the "f" is just a variable that essentially says, "Anything we do on f, we do to the file". Likewise, to start working with a new file, I wrote with open("newfile.txt", 'w') as g:. The "newfile.txt" is the name of the file. The "w" means you're opening up this file for writing to it instead of reading from it (if the file doesn't exist, it will create it; if it exists already, it will completely write over it). Then the "g" is just a variable I picked to refer to this file. So g.write(line) just writes the next line of text from the first file to the next line of text in the second file. I suppose you could use "f" again here, since at this point you've already read all of the lines from the old file. But using a different variable cuts down on any ambiguity of what file you're dealing with, especially if you ever wanted to change this so that you simultaneously have one file still open for reading as you have a second file open for writing.
Related
I'm trying to create a program using Python that will go through a file containing a git diff (in C code), go through the file, and remove the comments. I tried to read from the file and print a new comment-less version in a different file, but it doesn't seem to be working. I'm also now becoming aware that it will not work for multiline comments.
Here's my code:
write_path = "diff_file" # new file to write in
read_path = "text_diff" # text_diff is the original file with the diff
with open(read_path,'r') as read_file:
text_diff = read_file.read().lower()
for line in read_file:
if line.startswith("/*") and line.endswith("*/"):
with open(write_path, 'a') as write_file:
write_file.write(line + "/n")
For reference, I'm running it under WSL.
I tried this. I changed 'a' to 'w' (write) when opening the output file, and changed its position to avoid opening everytime. I also changed the if condition. That way when there is a comment line it is not printed to the new file.
Also, in endswith I included \n, since a new line is included at the end of the string. And deleted the \n when writing.
write_path = "diff_file" # new file to write in
read_path = "text_diff" # text_diff is the original file with the diff
with open(read_path,'r') as read_file:
text_diff = read_file.readlines()
with open(write_path, 'w') as write_file:
for line in text_diff:
if not (line.startswith("/*") and line.endswith("*/\n")):
write_file.write(line)
I want to do a lot of boring C# code replacements automatically through a python script. I read all lines of the file, transform them, truncate the whole file, write new strings and close it.
f = open(file, 'r+')
text = f.readlines()
# some changes
f.truncate(0)
for line in text:
f.write(line)
f.close()
All my changes are written. But some strange characters in the beginning of the file appear. I don't know how to avoid them. Even if I open with encoding='utf-8-sig' it doesn't help.
I tried truncate whole file besides the 1st line like this:
import sys
f.truncate(sys.getsizeof(text[0]))
for index in range(1, len(text), 1):
f.write(text[index])
But in this case more than 1st line is writing instead of only first line.
EDIT
I tried this:
f.truncate(len(text[0]))
for index in range(1, len(text), 1):
f.write(text[index])
And the first line has written correct but next one with the same issue. So I think this characters from the end of the file and I try to write after them.
f=open(file, 'r+')
text = f.readlines() # After reading all the lines, the pointer is at the end of the file.
# some changes
f.seek(0) # To bring the pointer back to the starting of the file.
f.truncate() # Don't pass any value in truncate() as it means number of bytes to be truncated by default size of file.
for line in text:
f.write(line)
f.close()
Check out this Link for more details.
I'm trying to delete lines from a file with certain criteria but when I run the script it just deletes the whole file. When I change the script to just 'read' the lines it returns the lines with the search criteria but when I open the file in 'write' mode it and change it from printing each line to remove each line it empties the whole thing.
#!/usr/bin/env python
f = raw_input('Enter filename > ')
with open(f, 'w+') as fobj:
criteria = raw_input('Enter criteria > ')
for eachLine in fobj:
if criteria in eachLine:
fobj.remove(eachLine)
break
fobj.close()
I hope you wanted to remove the line having particular criteria. You can simply create another file with and write the content in that file as following:
output = []
with open('test.txt', 'r') as f:
lines = f.readlines()
criteria = 'test'
output =[line for line in lines if criteria not in line]
fin = open('newfile.txt', 'wb')
fin.writelines(output)
From the docs:
w+ Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated. The stream is positioned at
the beginning of the file.
a+ Open for reading and writing. The file is created if it does not
exist. The stream is positioned at the end of the file. Subse-
quent writes to the file will always end up at the then current
end of file, irrespective of any intervening fseek(3) or similar.
so you are truncating the file on the line containing the with open. You probably want to create a new file with a different name and rename it at the end of your program.
I am trying to append a string to a file, if the string doesn't exit in the file. However, opening a file with a+ option doesn't allow me to do at once, because opening the file with a+ will put the pointer to the end of the file, meaning that my search will always fail. Is there any good way to do this other than opening the file to read first, close and open again to append?
In code, apparently, below doesn't work.
file = open("fileName", "a+")
I need to do following to achieve it.
file = open("fileName", "r")
... check if a string exist in the file
file.close()
... if the string doesn't exist in the file
file = open("fileName", "a")
file.write("a string")
file.close()
To leave the input file unchanged if needle is on any line or to append the needle at the end of the file if it is missing:
with open("filename", "r+") as file:
for line in file:
if needle in line:
break
else: # not found, we are at the eof
file.write(needle) # append missing data
I've tested it and it works on both Python 2 (stdio-based I/O) and Python 3 (POSIX read/write-based I/O).
The code uses obscure else after a loop Python syntax. See Why does python use 'else' after for and while loops?
You can set the current position of the file object using file.seek(). To jump to the beginning of a file, use
f.seek(0, os.SEEK_SET)
To jump to a file's end, use
f.seek(0, os.SEEK_END)
In your case, to check if a file contains something, and then maybe append append to the file, I'd do something like this:
import os
with open("file.txt", "r+") as f:
line_found = any("foo" in line for line in f)
if not line_found:
f.seek(0, os.SEEK_END)
f.write("yay, a new line!\n")
There is a minor bug in the previous answers: often, the last line in a text file is missing an ending newline. If you do not take that that into account and blindly append some text, your text will be appended to the last line.
For safety:
needle = "Add this line if missing"
with open("filename", "r+") as file:
ends_with_newline = True
for line in file:
ends_with_newline = line.endswith("\n")
if line.rstrip("\n\r") == needle:
break
else: # not found, we are at the eof
if not ends_with_newline:
file.write("\n")
file.write(needle + "\n") # append missing data
I am trying to add a line to the end of a txt file. I have been reading some posts here and trying differents options, but, for some reason, the new line is neved added after the last one, it is just appended next to the last one.
So I was wondering what I am doing wrong....here I am showing my tests:
TEST 1:
#newProt is a new data entered by the user in this case 12345
exists = False
f = open('protocols.txt', 'a+')
for line in f:
if newProt == line:
exists = True
if not exists:
f.write(newProt)
f.close()
txt file after this code:
2sde45
21145
we34z12345
TEST 2:
exists = False
with open('protocols.txt', 'r+') as f:
for line in f:
if newProt == line:
exists = True
if not exists:
f.write(newProt)
txt file after this code: exactly the same as above...
And, like this, I have tested some combinations of letters to open the file, rb+, w, etc but for some reason I never get the desired output txt file:
2sde45
21145
we34z
12345
So I do not know what I am doing wrong, I am following some examples I gor from some other posts here.
Try this:
exists = False
f = open('protocols.txt', 'a+')
for line in f:
if newProt == line:
exists = True
if not exists:
f.write('\n' + newProt)
f.close()
This adds the new line character to the end of the file then adds 'newProt'.
EDIT:
The reason why your code did not produce the desired result is because you were simply writing a string to the file. New lines in text are not really 'in' the text file. The text file is literally a series of bytes known as chars. The reason why various applications such as text editors show you new lines is because it interprets certain characters as formatting elements rather than letters or numbers.
'\n' is one such formatting character (in the ASCII standard), and it tells your favorite text editor to start a new line. There are others such as '\t' which makes a tab.
Have a look at the wiki article on Newline character for more info
You can use f.seek(-x,x), reach the last line and then f.write().
Otherwise my understanding is if you open a file in "a" (append) mode, it'll anyways be written in the end
Refer to this link: Appending line to a existing file having extra new line in Python