Копирование каждой строки tsv в другой tsv на основе условия

У меня есть каталог сказать /var/work/X/ где у меня есть сотни файлов TSV Эти файлы называются call1.tsv, call2.tsv ,call3.tsv и т.п.

Один ЦВ выглядит так (назовите этот call1.tsv):

field1 field2 field3 field4 field5
abc   command text  media  'hello'
xyz  tts  reply  sms  'hi'
mno  server reply sms 'done'
pqr command text media 'search'

Я хочу пройти через каждую строку, выбрать только строки с 3-м столбцом в качестве ответа или field3= reply и сохранить его в файле с тем же именем в другом каталоге /var/work/processed/Наконец мне нужно иметь в /var/work/processed/call1.tsv

field1 field2 field3 field4 field5
xyz  tts  reply  sms  'hi'
mno  server reply sms 'done'

Мне нужно пройти все tsvs, как это. Пожалуйста, помогите мне с кодом

import  os, sys,glob,codecs

import csv
csv.field_size_limit(sys.maxint)
input_dir = "/var/work/X"
print input_dir

output_dir= "/var/work/processed"
print output_dir
# Get names of all tsv files
tsvs= glob.glob(os.path.join(input_dir,'*.tsv'))
for tsvfile in tsvs:
    outtsvfile=str(tsvfile).split('/')[-1]
    print outtsvfile

    data=csv.reader(open(tsvfile,'rb'),delimiter = "\t")

    try:
        with open(os.path.join(output_dir, outtsvfile)) as outputfile:
           csvwriter=csv.writer(outputfile,delimiter='\t')
        for row in data:

            if "reply" in row[2]:
                  csvwriter.writerow(row)
    except csv.Error as e:
            print "%s" %e
            print "%s" %traceback.format_exc()

Я получаю это: Значение ошибки: I?O операция над закрытым файлом

2 ответа

Решение

Я думаю, что ваша первая проблема

    with open(os.path.join(output_dir, outtsvfile)) as outputfile:
       csvwriter=csv.writer(outputfile,delimiter='\t')
    for row in data:    # <= bad indentation!
        if "reply" in row[2]:
              csvwriter.writerow(row)

ваш цикл for должен быть внутри оператора with (т. е. с отступом еще на один уровень); в противном случае файл закрывается, прежде чем вы пытаетесь читать с него.

Вот некоторый код для перебора нужных вам файлов:

IN_DIR = "/var/work/X/"
OUT_DIR = "/var/work/processed/"

def get_file_names(dir, ext=""):
    for fname in os.listdir(dir):
        if fname.endswith(ext) and os.path.isfile(fname):
            yield fname

def process_file(in_file, out_file):
    # your file-processing code goes here
    print("{} => {}".format(in_file, out_file))

def main():
    for fname in get_file_names(IN_DIR, ".tsv"):
        process_file(
            os.path.join(IN_DIR, fname),
            os.path.join(OUT_DIR, fname)
        )

if __name__=="__main__":
    main()

и ваш код обработки файлов должен быть что-то вроде

import csv
import sys

if sys.hexversion < 0x3000000:
    READ_MODE = "rb"   # Python 2.x
    WRITE_MODE = "wb"
else:
    READ_MODE = "rU"   # Python 3.x
    WRITE_MODE = "wU"

def read_csv(fname, skip_header=False, **kwargs):
    with open(fname, READ_MODE) as inf:
        incsv = csv.reader(inf, **kwargs)
        if skip_header:
            next(incsv, None)
        for row in incsv:    # or 'yield from incsv' if your Python supports it
            yield row        #

def write_csv(fname, rows, header=None, **kwargs):
    with open(fname, WRITE_MODE) as outf:
        outcsv = csv.writer(outf, **kwargs)
        if header:
            outcsv.writerow(header)
        outcsv.writerows(rows)

def process_file(in_file, out_file):
    data = read_csv(in_file, delimiter="\t")
    header = next(data, [])
    filtered = (row for row in data if row[2] == "reply")
    write_csv(out_file, filtered, header=header, delimiter="\t")

Использовать csv модуль:

import csv

with open('output.tsv') as output_file:
    csv_writer = csv.writer(output_file,  delimiter='\t')

with open('call1.tsv') as input_file:
    csv_reader = csv.reader(input_file, delimiter='\t')
    for row in csv_reader:
        if 'reply' == row[2]:  # I think you meant field 3
            csv_writer.writerow(row)

csv_reader.close()
csv_writer.close()

Сделайте это для всех файлов в вашем входном каталоге. Чтобы просмотреть и просмотреть все tsv-файлы во входном каталоге, вы можете использовать os модули listdir метод.

Другие вопросы по тегам