2015-08-21 2 views
3

Предисловие. Я довольно новичок в Python, имея больше опыта на другом языке.Анализ текстового файла на python и вывод в CSV

У меня есть текстовый файл с одним списком столбцов, строк в родовом (но слегка варьируя) формат «./abc123a1/type/1ab2_x_data_type.file.type»

Мне нужно извлечь abc123a1 и 1ab2 части из всех нескольких сотен строк и помещают их под два столбца (столбцы a и b) в csv. Иногда может быть «1ab2_a» и «1ab2_b», но только хочу один 1ab2. Поэтому я хотел бы захватить «1ab2_a» и игнорировать все остальные.

У меня есть регулярное выражение, которое я думаю, что будет работать:

tmp = list() 
if re.findall(re.compile(r'^([a-zA-Z0-9]{4})_'), x): 
    tmp = re.findall(re.compile(r'^([a-zA-Z0-9]{4})_'), x) 
elif re.findall(re.compile(r'_([a-zA-Z0-9]{4})_'), x): 
    tmp = re.findall(re.compile(r'_([a-zA-Z0-9]{4})_'), x) 
if len(tmp) == 0: 
    return None 
elif len(tmp) > 1: 
    print "ERROR found multiple matches" 
    return "ERROR" 
else: 
    return tmp[0].upper() 

Я пытаюсь сделать этот шаг за шагом сценария и тестирования вещей, чтобы убедиться, что он работает, но это просто не так.

import sys 
import csv 

listOfData = [] 

with open(sys.argv[1]) as f: 
    print "yes" 
    for line in f: 
     print line 
    for line in f: 
     listOfData.append([line]) 
print listOfData 

with open('extracted.csv', 'w') as out_file: 
    writer = csv.writer(out_file) 
    writer.writerow(('column a', 'column b')) 
    writer.writerows(listOfData) 

print listOfData 

Все еще не в состоянии получить что-либо в формате CSV, кроме заголовков столбцов, намного меньше разобран версия!

Есть ли у кого-нибудь лучшие идеи или форматы, в которых я мог бы это сделать? Друг упоминал о том, как смотреть в glob.glob, но мне не повезло, что это так работает.

+0

Когда вы печатаете 'listOfData', это делает e данные, которые вы хотите? –

+0

"* Так что я хочу захватить« 1ab2_a »и игнорировать все остальные. *« Не уверен, чтобы хорошо понять это предложение. Вы хотите извлечь '1ab2' или' 1ab2_a'? –

+0

Не могли бы вы отредактировать вопрос, чтобы добавить еще несколько строк ввода? Также добавьте, какой будет ожидаемый результат для этого ввода. –

ответ

0

Я не уверен, о своем регулярном выражении (это, скорее всего, не работает), но причина, почему ваше текущее (не регулярное выражение, простой) код не работает, потому что -

with open(sys.argv[1]) as f: 
    print "yes" 
    for line in f: 
     print line 
    for line in f: 
     listOfData.append([line]) 

Как вы можете см., что вы сначала итерации по каждой строке в файле и ее печати, это должно быть хорошо, но после окончания цикла указатель файла находится в конце файла, поэтому попытка повторить его снова не приведет к результату. Вы должны только перебирать его один раз, а также печатать и добавлять в него список. Пример -

with open(sys.argv[1]) as f: 
    print "yes" 
    for line in f: 
     print line 
     listOfData.append([line]) 
0

Я думаю, что по крайней мере часть проблемы заключается в том, что две for петли в следующих:

with open(sys.argv[1]) as f: 
    print "yes" 
    for line in f: 
     print line 
    for line in f: 
     listOfData.append([line]) 

Первый из них print s все линии f, так что ничего не осталось для второй для повторения, если вы не первый f.seek(0) и перемотаете файл.

Альтернативный способ будет просто так:

with open(sys.argv[1]) as f: 
    print "yes" 
    for line in f: 
     print line 
     listOfData.append([line]) 

Это трудно сказать, если ваши регулярные выражения в порядке, не более чем в одной строке входных данных выборки.

2

ИМХО, вы были недалеко от его работы. Проблема в том, что вы читаете, как только весь файл просто печатает строки, а затем (один раз в конце файла) вы пытаетесь поместить их в список ... и получите пустой список!

Вы должны прочитать файл только один раз:

import sys 
import csv 

listOfData = [] 

with open(sys.argv[1]) as f: 
    print "yes" 
    for line in f: 
     print line 
     listOfData.append([line]) 
print listOfData 

with open('extracted.csv', 'w') as out_file: 
    writer = csv.writer(out_file) 
    writer.writerow(('column a', 'column b')) 
    writer.writerows(listOfData) 

print listOfData 

, когда он работает, вы все равно должны использовать регулярное выражение, чтобы получить соответствующие данные, чтобы поместить в файл CSV

0

Вы уверены, что вам нужно все регулярных выражений? Кажется, вы разбираете список путей и имен файлов. Путь может быть разделен с помощью команды split, например:

print "./abc123a1/type/1ab2_a_data_type.file.type".split("/") 

Даст:

['.', 'abc123a1', 'type', '1ab2_a_data_type.file.type'] 

Затем можно создать set, состоящий из второй записи и вплоть до «_» в четвертая запись, например

('abc123a1', '1ab2') 

Это можно затем использовать для печати только первой записи из каждого:

pairs = set() 

with open(sys.argv[1], 'r') as in_file, open('extracted.csv', 'wb') as out_file: 
    writer = csv.writer(out_file) 

    for row in in_file: 
     folders = row.split("/") 
     col_a = folders[1] 
     col_b = folders[3].split("_")[0] 

     if (col_a, col_b) not in pairs: 
      pairs.add((col_a, col_b)) 
      writer.writerow([col_a, col_b]) 

Так для входа, глядя, как это:

./abc123a1/type/1ab2_a_data_type.file.type 
./abc123a1/type/1ab2_b_data_type.file.type 
./abc123a2/type/1ab2_a_data_type.file.type 
./abc123a3/type/1ab2_a_data_type.file.type 

Вы бы получить файл CSV ищет например:

abc123a1,1ab2 
abc123a2,1ab2 
abc123a3,1ab2 
Смежные вопросы