DragonPig
DragonPig

Reputation: 65

How to delete a row in csv file based on multiple conditions?

I want to read a CSV file and delete a row in that CSV file based on three conditions, type, srcaddr, dstaddr.

So for example, if i enter something like first condition is 'icmp', second condition is '10.0.0.1', third condition is '10.0.0.2', it will only delete that certain row.

I have tried using this code but it only allows me to delete based on one condition only, how can I modify it to allow it to delete based on multiple conditions?

#code that I used to delete a row in CSV file based on only one condition.

import csv
import sys


with open('firewall-policies-test.csv', "rb") as f:
    data = list(csv.reader(f))

with open('firewall-policies-test.csv', "wb") as f:
    writer = csv.writer(f)
    for row in data:
        if row[0] != 'icmp':
              writer.writerow(row)   






 #code for CSV File
 type,srcaddr,dstadrr
 icmp,10.0.0.1,10.0.0.2
 tcp,10.0.0.1,10.0.0.2

It always give me an error saying list index out of range when i am trying to use and & or operators..

Traceback (most recent call last):
  File "deletecsv.py", line 11, in <module>
    if row[0] != "icmp" and row[1] != '10.0.0.1' and row[2] != '10.0.0.2':
IndexError: list index out of range

Upvotes: 2

Views: 1711

Answers (2)

Patrick Artner
Patrick Artner

Reputation: 51643

You most probably have empty lines in your data - it may be simply a \n after the last line. It is parsed as well and does not contain any elements so row is a zero-length list - accessing row[1] then lets your program crash.

Create demo file:

with open("firewall-policies-test.csv","w") as f:
     f.write("""type,srcaddr,dstadrr
 icmp,10.0.0.1,10.0.0.2
 tcp,10.0.0.1,10.0.0.2
 bla,10.0.0.3,10.0.0.4
""") # here is a line that does not hold 3 values - it holds nothing (== [])

Fix:

import csv
import sys 

# dont write / read text as binary    
with open('firewall-policies-test.csv', "r") as f:
    data = list(csv.reader(f))

with open('firewall-policies-test.csv', "w") as f:
    writer = csv.writer(f)
    for row in data:
        if row: # only use non-empty lines (or use if len(row)>2)
            if row[0] != 'icmp' and row[1] != '10.0.0.1' and row[2] != '10.0.0.2':
                  writer.writerow(row)

Test:

with open("firewall-policies-test.csv","r") as f:
    print(f.read())

Output:

type,srcaddr,dstadrr
 bla,10.0.0.3,10.0.0.4

The condition I use will remove any line that contains either of the conditions - to only delete rows that fullfill all your conditions use:

            if not (row[0] == 'icmp' and row[1] == '10.0.0.1' and row[2] == '10.0.0.2'): 
                writer.writerow(row)

Upvotes: 2

Scarysize
Scarysize

Reputation: 4281

You can "chain" multiple conditions using the logical operator and or or:

if row[0] != 'icmp' and row[1] != 'foo' and row[2] != 'bar':
  # do thing

Here is are some more example and explanations:

https://thomas-cokelaer.info/tutorials/python/boolean.html#boolean-examples

Upvotes: 2

Related Questions