2013-09-24 4 views
1

У меня есть несколько каталогов, каждый с несколькими файлами в:Python3: запись информации из текстового файла в файл CSV

Ce 
+---top.txt 
+---X0.0   
|  | 
|  +---Y0.0 
|  |  | 
|  |  +---X0.0Y0.0Z0.0.dat 
|  |  +---X0.0Y0.0Z0.0.out 
|  |  +---X0.0Y0.0Z0.05.dat 
|  |  +---X0.0Y0.0Z0.05.out 
|  +---Y0.05 
|   | 
|   +---X0.0Y0.05Z0.0.dat 
|  |  +---X0.0Y0.0Z0.05.out 
|   +---X0.0Y0.05Z0.05.dat 
|   +---X0.0Y0.05Z0.05.out 
+---X0.05 
     | 
     +---Y0.0 
     |  | 
     |  +---X0.0Y0.0Z0.0.dat 
     |  +---X0.0Y0.0Z0.0.out 
     |  +---X0.0Y0.0Z0.05.dat 
     |  +---X0.0Y0.0Z0.05.out 
     +---Y0.05 
      | 
      +---X0.0Y0.05Z0.0.dat 
      +---X0.0Y0.05Z0.0.out 
      +---X0.0Y0.05Z0.05.dat 
      +---X0.0Y0.05Z0.05.out 

Я пытаюсь извлечь необходимую информацию из файлов «.out» и писать в файл csv. Для этого я разработал следующий код:

import os 
import csv 

with open('results.csv', 'a', newline='') as f: 
    writer=csv.writer(f) 
    writer.writerow(['Filename', 'Optimisation Achieved?', 'Final Energy', 'Number of Defects', 'Defect Charge', 'M-L Centre X', 'M-L Centre Y', 'M-L Centre Z', 'Defect X', 'Defect Y', 'Defect Z', 'Defect Energy']) 
    for root, dirs, files in os.walk('.'): 
     for filename in files: 
      if filename.endswith('.out'): 
       file = os.path.join(root, filename) 
       with open(file, 'r') as reader: 
        opt_cnt=0 
        for line in reader: 
         s=line.strip() 
         if s=='**** Optimisation achieved ****': 
          opt_cnt+=1 
          if opt_cnt==1: 
           opt1='Y' + str(opt_cnt) 
          if opt_cnt==2: 
           opt2='Y' + str(opt_cnt) 
          else: 
           opt2='N' 
         elif s.startswith('Final energy='): 
          Final=s[18:31] 
         elif s.startswith('Total Number of Defects'): 
          Number=s[31] 
         elif s.startswith('Total charge on defect'): 
          Q=s[-4:] 
         elif s.startswith('Defect centre'): 
          centrex=s[21:28] 
          centrey=s[31:37] 
          centrez=s[40:46] 
         elif s.startswith('Atom/Fractional'): 
          coordx=s[40:49] 
          coordy=s[51:60] 
          coordz=s[62:71] 
         elif s.startswith('Final defect energy'): 
          Defect_Energy=s[-13:] 
       writer.writerow([filename, opt1, Final, Number, centrex, centrey, centrez, coordx, coordy, coordz, Defect_Energy]) 

Однако, это производит следующее сообщение об ошибке:

Traceback (самый последний вызов последний):
файл «C: \ Users \ Rebecca \ Dropbox \ Brannerite \ Published Potentials \ interstitials \ Grid \ Ce \ results.py ", строка 39, в
writer.writerow ([имя файла, opt1, Final, Number, centrex, centrey, centrez, coordx, coordy, coordz, Defect_Energy])
NameError: name 'Final' не определен

[Изменение размера отступа последней строки в моем коде изменяет, какая из переменных появляется в имениError: поскольку в коде есть 16 отступов (то же самое, что и NameError задано с 20 отступов); изменяя это 8, 12 или 24 дает 'NameError: имя „opt1“ не определен]

Я должен сказать, что большая часть этого кода [удалить строки, относящиеся к os.walk] был успешно использован для другой набор файлов (все они были в одном каталоге).

Может ли кто-нибудь предложить, где ошибка исходит из приведенного выше кода и как его можно исправить?

ответ

1

Если есть файл out, у которого нет строки, которая начинается с Final energy=, Final остается неопределенным. Вы можете определить значения по умолчанию для Final, Number и т.д. переменные, которые определены в цикле, например, установить их все undefined строки:

Final = Number = ... = 'undefined' 
file = os.path.join(root, filename) 
with open(file, 'r') as reader: 
    opt_cnt=0 
    for line in reader: 
     ... 
+1

спасибо за подсказку. Каждый файл (или, по крайней мере, должен) должен иметь эту строку - проблема заключалась в том, что она не была найдена, потому что я сделал ошибку, чтобы изменить случай некоторых букв в строке. Тем не менее, ваш ответ дал мне ключ к тому, где искать - без этого я бы этого не сделал ... – user2696225

0

Я думаю, что вы хотите иметь 2 вары Final и opt1 определены. Что не так в коде

writer.writerow([filename, opt1, Final, Number, centrex, centrey, centrez, coordx, coordy, coordz, Defect_Energy]) 

, как ваш код позволяет определить только один из них или OPT1 или Final из-за, если/Элиф конструкция:

if s=='**** Optimisation achieved ****': 
    opt_cnt+=1 
    if opt_cnt==1: 
     opt1='Y' + str(opt_cnt) 
elif s.startswith('Final energy='): 
    Final=s[18:31] 

Может попробовать определения значений по умолчанию заранее или изменение применяемой логики