I have a file like this:
a
D
c
a
T
c
a
R
c
I want to delete from specific line (in this case 3) until another specific line (in this case 5), so the file would look like:
a
D
c
a
R
c
CodePudding user response:
I prefer to output into another file, so I can debug both input and output files if necessary. If you need to delete in the same file, write to 'my_file.txt' instead of 'my_file2.txt'. The files 'my_file.txt' and 'my_file2.txt' are the input and output respectively in the original question.
with open('my_file.txt') as f:
lines = f.readlines()
f.close()
with open('my_file2.txt', 'w') as write_file:
for i, line in enumerate(lines):
if i!=2 and i!=3 and i!=4: #skip lines 3 to 5
write_file.write(line)
write_file.close()
Edit: On the other hand, if the input list is the following:
andy
David
catherine
anderson
Tera
cathy
angel
Rachel
calvin
You can set the rules for deletion, and run the code
contacts_to_delete = ['catherine', 'Tera', 'angel']
with open('my_file.txt') as f:
lines = f.readlines()
f.close()
with open('my_file2.txt', 'w') as write_file:
for contact in lines:
if contact.strip('\n') not in contacts_to_delete:
write_file.write(contact)
write_file.close()
Output:
andy
David
anderson
cathy
Rachel
calvin
CodePudding user response:
I think this should work:
def delete_line_range(filename, start_line, end_line):
# read all lines
with open(filename, 'r') as f:
lines = f.readlines()
f.close()
with open(filename, 'w') as f:
# iterate trough lines
for i in range(len(lines)):
# check if line is out of range
if i < start_line or i > end_line:
f.write(lines[i])
f.close()
return
Or if you want to delete multiple ranges
def delete_line_ranges(filename, line_ranges):
# read all lines
with open(filename, 'r') as f:
lines = f.readlines()
f.close()
with open(filename, 'w') as f:
# iterate trough lines
for i in range(len(lines)):
# check if line is in range
in_range = False
for line_range in line_ranges:
if i >= line_range[0] and i <= line_range[1]:
in_range = True
break
# if not in range, write line
if not in_range:
f.write(lines[i])
f.close()
return
Where line_ranges
is a list of tuples containing start and end line numbers.
Be aware that in both of these functions the line numbers start at 0. Means if you want to delete line 3 to 5 like in your example you need to subtract 1 from both start and end line number.
delete_line_range('test.txt', 2, 4) # deletes line 3 to 5 if you start counting from 1
Edit
Deleting Contacts out of vcf file.
Get range of specific contact:
def get_contact_range(filename, name):
# read all lines
with open(filename, 'r') as f:
lines = f.readlines()
f.close()
for i in range(len(lines)):
# check if line is start of contact
if lines[i].startswith('BEGIN:VCARD'):
start_line = i
continue
if name in lines[i]:
for j in range(i, len(lines)):
# check if line is end of contact
if lines[j].startswith('END:VCARD'):
end_line = j
return (start_line, end_line)
return None
print(get_contact_range('test.vcf', 'John Doe'))
test.vcf
BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//macOS 11.5.2//EN
N:Doe;John;;;
FN:John Doe
ORG:Sharpened Productions;
EMAIL;type=INTERNET;type=HOME;type=pref:[email protected]
EMAIL;type=INTERNET;type=WORK:[email protected]
TEL;type=CELL;type=VOICE;type=pref:123-456-7890
ADR;type=HOME;type=pref:;;12345 First Avenue;Hometown;NY;12345;United States
ADR;type=WORK:;;67890 Second Avenue;Businesstown;NY;67890;United States
NOTE:The man I met at the company networking event. He mentioned that he had some potential leads.
item1.URL;type=pref:https://fileinfo.com/
item1.X-ABLabel:_$!!$_
BDAY:2000-01-01
END:VCARD
Output:
(0, 15)
Combine the above functions:
def delete_contact(filename, name):
# get start and end line of contact
contact_range = get_contact_range(filename, name)
# delete contact
delete_line_range(filename, contact_range[0], contact_range[1])
return
Multiple Contacts at once:
def delete_contacts(filename, names):
# get start and end line of contacts
line_ranges = []
for name in names:
contact_range = get_contact_range(filename, name)
line_ranges.append((contact_range[0], contact_range[1]))
# delete contacts
delete_line_ranges(filename, line_ranges)
return