you can just consume the first line of the file to read and write it back in the file to be written:
with open('master.csv', 'r') as master, open('match.csv', 'w') as matched:
matched.write(next(master)) # can't use readline when iterating on the file afterwards
Seems that you really need csv module, though, for the rest. I'll edit my answer to attempt something in that direction
With the csv module, no need for those unsafe split. Comma is the default separator and quotes are also handled properly. So I'd just write:
import csv
with open('master.csv', 'r') as master, open('match.csv', 'w') as matched:
cr = csv.reader(master)
cw = csv.writer(matched)
cw.writerow(next(cr)) # copy title
for row in cr: # iterate on the rows, already organized as lists
if any(city in row[5] for city in citys) and \
any(state in row[6] for state in states) and \
not any(category in row[2] for category in categorys):
cw.writerow(row)
BTW your filter checks that city is contained in row[5], but maybe you'd like an exact match. Ex: "York" would match "New York", which is probably not what you want. So my proposal would be using in to check if the string is in the list of strings, for each criterion:
import csv
with open('master.csv', 'r') as master, open('match.csv', 'w') as matched:
cr = csv.reader(master)
cw = csv.writer(matched)
cw.writerow(next(cr)) # copy title
for row in cr:
if row[5] in citys and row[6] in states and not row[2] in categorys:
cw.writerow(row)
which can be even bettered using generator comprehension and write all lines at once:
import csv
with open('master.csv', 'r') as master, open('match.csv', 'w') as matched:
cr = csv.reader(master)
cw = csv.writer(matched)
cw.writerow(next(cr)) # copy title
cw.writerows(row for row in cr if row[5] in citys and row[6] in states and not row[2] in categorys)
note that citys, states, and categorys would be better as sets rather than lists so lookup algorithm is much faster (you didn't provide that information)