Reputation: 51
I am opening a text file, searching to find a specific line(writing previous lines to a new file). Once that line ("BASE CASE") is found, I want to search for a specific block of text to delete form a file.
I have constructed some code through researching similar problems online. Right now, it only creates an empty new eve file. It also gives me an error that "this file is being used in python" when I try to delete the blank files. An example of what the old file looks like would be this: There can be an unknown number of monitors for each block.
xxxoijasdf
Monitor 4
aowijefoi
BASE CASE
Monitor 5
Monitor 3
Monitor 2
Item 1 Item 2
End
Monitor 3
Monitor 4
Item 3 Item 4
End
Monitor 1
Item 5 Item 6
End
The code I currently have is:
longStr1 = (r"C:\Users\jrwaller\Documents\Automated Eve\NewTest.txt")
endfile1 = (r"C:\Users\jrwaller\Documents\Automated Eve\did we do it yet.txt")
search_item = "Item 3 Item 4"
with open(longStr1, "r") as f:
with open(endfile1, "w") as new_file:
lines = f.readlines()
i=0
while i < 2000:
for line in f:
if lines[i] != 'BASE CASE':
new_file.write(lines[i])
else:
new_file.write(lines[i])
newfile.write(lines[i+1])
block = ''
for line in f:
if block:
block += line
if line.strip() == 'End':
if search_item not in block: new_file.write(block + '\n')
block = ''
elif line.startswith('Monitor'):
block = line
new_file.close()
f.close()
I am hoping to reprint the old txt file to the new file while deleting the block of text between the first 'End' and 'Monitor 1'. Current problems include the output file being blank and the output file being left open in python.
Upvotes: 0
Views: 91
Reputation: 51
longStr1 = (r"C:\Users\jrwaller\Documents\Automated Eve\NewTest.txt")
endfile1 = (r"C:\Users\jrwaller\Documents\Automated Eve\did we do it yet.txt")
search_item = "Item 3 Item 4"
with open(longStr1, "r") as f:
with open(endfile1, "w+") as new_file:
state = 1
write_out = True
for line in f:
if state == 1:
write_out = True
if "BASE CASE" in line:
state = 2
elif state == 2:
if line == '\n':
write_out = True
state = 3
elif state == 3:
write_out = True
block = ''
for line in f:
if block:
block += line
if line.strip() == 'End':
if search_item not in block: new_file.write(block + '\n')
block = ''
elif line.startswith('Monitor'):
block = line
if search_item in line:
state = 4
write_out = False
elif state == 4:
write_out = False
if "End" in line:
state = 5
write_out = False
elif state == 5:
if "Monitor" in line:
write_out = True
state = 6
elif state == 6:
write_out = True
if write_out:
new_file.write(line)
f.close()
new_file.close()
Upvotes: 1
Reputation: 77850
You are describing a simple state machine. Your states are:
Since there are only two actions ("write" and "don't write"), you can handle this with a state variable and an action flag. Something like this:
state = 1
write_out = True
for line in f:
# Looking for "BASE CASE"; write line until then
if state == 1:
if "BASE CASE" in line:
state = 2
# Look for start of unwanted block
elif state == 2:
if "End" in line:
state = 3
write_out = False
# Look for end of unwanted block
...
# Acknowledge moving past "Monitor 1"
...
# Iterate through rest of file
...
if write_out:
new_file.write(line)
If you prefer, you can write this as a sequence of implicit-state loops:
while not "BASE CASE" in line:
new_file.write(line)
line = f.readline()
while not "End" in line:
new_file.write(line)
line = f.readline()
while not "Monitor 1" in line:
# Don't write this block to the output
line = f.readline()
...
Can you take it from there?
Upvotes: 1