Reputation: 6949
I am trying to remove specific line numbers from a file in python in a way such as
./foo.py filename.txt 4 5 2919
Where 4 5 and 2919 are line numbers
What I am trying to do is:
for i in range(len(sys.argv)):
if i>1: # Avoiding sys.argv[0,1]
newlist.append(int(sys.argv[i]))
Then:
count=0
generic_loop{
bar=file.readline()
count+=1
if not count in newlist:
print bar
}
it prints all the lines in original file (with blank spaces in between)
Upvotes: 2
Views: 253
Reputation: 133574
The fileinput
module has an inplace=True
option that redirects stdout to a tempfile which is automatically renamed after for you.
import fileinput
exclude = set(map(int, sys.argv[2:]))
for i, line in enumerate(fileinput.input('filename.txt', inplace=True), start=1):
if i not in exclude:
print line, # fileinput inplace=True redirects stdout to tempfile
Upvotes: 1
Reputation: 250961
You can try something like this:
import sys
import os
filename= sys.argv[1]
lines = [int(x) for x in sys.argv[2:]]
#open two files one for reading and one for writing
with open(filename) as f,open("newfile","w") as f2:
#use enumerate to get the line as well as line number, use enumerate(f,1) to start index from 1
for i,line in enumerate(f):
if i not in lines: #`if i not in lines` is more clear than `if not i in line`
f2.write(line)
os.rename("newfile",filename) #rename the newfile to original one
Note that for the generation of temporary files it's better to use tempfile
module.
Upvotes: 2
Reputation: 287885
You can use enumerate
to determine the line number:
import sys
exclude = set(map(int, sys.argv[2:]))
with open(sys.argv[1]) as f:
for num,line in enumerate(f, start=1):
if num not in exclude:
sys.stdout.write(line)
You can remove start=1
if you start counting at 0. In the above code, the line numbering starts with 1:
$ python3 so-linenumber.py so-linenumber.py 2 4 5
import sys
with open(sys.argv[1], 'r') as f:
sys.stdout.write(line)
If you want to write the content to the file itself, write it to a temporary file instead of sys.stdout, and then rename that to the original file name (or use sponge on the command-line), like this:
import os
import sys
from tempfile import NamedTemporaryFile
exclude = set(map(int, sys.argv[2:]))
with NamedTemporaryFile('w', delete=False) as outf:
with open(sys.argv[1]) as inf:
outf.writelines(line for n,line in enumerate(inf, 1) if n not in exclude)
os.rename(outf.name, sys.argv[1])
Upvotes: 3
Reputation: 31621
import sys
# assumes line numbering starts with 1
# enumerate() starts with zero, so we subtract 1 from each line argument
omitlines = set(int(arg)-1 for arg in sys.argv[2:] if int(arg) > 0)
with open(sys.argv[1]) as fp:
filteredlines = (line for n,line in enumerate(fp) if n not in omitlines)
sys.stdout.writelines(filteredlines)
Upvotes: 2