0

I'm having trouble finding clear and concise methods of removing a select row from a CSV using the CSV module (not the Panda since it's required to be installed). I would also like to remove a range of rows separately. Every article and every question I've seen either or abroad are not clear at all and tend to include specific logic people are asking about. I just want a clear cut answer that is very simple.

I would like to use argv to provide a filename, beginning row number, and end row numbers. So something like python Script.py /CSVfile.csv 1 5, meaning the file name and remove rows 1 through 5 (beginning and ending). I'm new to Python scripting and I get halfway there, but there is always some logic people include that isn't relevant to what I need to do. I just keep getting blocked (as I typically do when trying to code), any help is appreciated.

import csv
import sys

var1 = sys.argv[1]
var2 = sys.argv[2]
var3 = sys.argv[3]

with open (var1, 'w') as file1:
   reader = csv.reader(file1)
   for line in reader:
      file1.writer()
Devin St. Clair
  • 187
  • 1
  • 9
  • 1
    Since you can't modify a file inplace while iterating over it, you should create another file and just write the rows you want to it. – spitfire21 Nov 17 '17 at 15:48
  • 1
    Yes. Read original file -> Put it's content into a data structure -> Change elements of that data structure -> Write it to new file or overwrite the original – Artsiom Praneuski Nov 17 '17 at 15:53
  • 1
    You can use fileinput inplace to overwrite the original file with the new file. https://docs.python.org/3/library/fileinput.html – spitfire21 Nov 17 '17 at 16:01

2 Answers2

1

similar question here

with open("foo.txt", "r+") as f:
     old = f.read() # read everything in the file
     f.seek(0) # rewind
     f.write("new line\n" + old) # write the new line before

go to line number using seek and add '\n' or whatever.

manickam
  • 21
  • 1
1

Just enumerate the lines and do not copy them if their index is in the range you want to exclude:

import csv
import sys

var1 = sys.argv[1]
var2 = sys.argv[2]
var3 = sys.argv[3]

with open (var1, 'r') as file1:
   reader = csv.reader(file1)
   for i, line in enumerate(reader):
      if (i < var2) or (i > var3):
          # process line...

If you want to filter the file in place, you would write the selected rows to a temporary file and finally rename to new file to the old name, but here there are no valid reason for parsing the rows

import sys
import tempfile

var1 = sys.argv[1]
var2 = sys.argv[2]
var3 = sys.argv[3]

(file2, name2) = tmpfile.msktemp()     # get a temporary file
try:
    with open (var1, 'r') as file1:
       for i, line in enumerate(file1):
          if (i < var2) or (i > var3):   # copy selected lines to temp file
              dummy = file2.write(line)
    file2.close()
except:
    remove(name2) # error: remove tempfile
    file2 = None
if file2 is not None:      # successful copy: rename to initial name
    remove(var1)
    rename(name2, var1)
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252