Создать выходной файл с несколькими строками (Python) - PullRequest
5 голосов
/ 01 марта 2011

У меня есть файл с конкретными данными, которые я хотел бы получить.

Файл выглядит так:

DS User ID 1  
random garbage  
random garbage  
DS  N user name 1   
random garbage  
DS User ID 2   
random garbage  
random garbage  
DS  N user name 2

Пока у меня есть:

import sys  
import re  
f = open(sys.argv[1])

strToSearch = ""

for line in f:
        strToSearch += line

patFinder1 = re.compile('DS\s+\d{4}|DS\s{2}\w\s{2}\w.*|DS\s{2}N', re.MULTILINE)

for i in findPat1:  
    print(i)

Мой вывод на экран выглядит следующим образом:

DS user ID 1  
DS  N user name 1  
DS user ID 2  
DS  N user name 2   

Если я пишу в файл, используя:

outfile = "test.dat"   
FILE = open(outfile,"a")  
FILE.writelines(line)  
FILE.close()  

Все помещается в одну строку:

DS user ID 1DS  N user name 1DS user ID 2DS  N user name 2 

Я могу жить с первым сценарием для выхода. Хотя в идеале я хотел бы убрать «DS» и «DS N» из выходного файла и разделить их запятыми.

User ID 1,user name 1  
User ID 2, username 2

Есть идеи, как этого добиться?

Ответы [ 4 ]

5 голосов
/ 01 марта 2011

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

Из приведенного выше примера ввода / вывода можно быстро создать рабочий пример кода:

out = open("test.dat", "a") # output file

for line in open("input.dat"):
    if line[:3] != "DS ": continue # skip "random garbage"

    keys = line.split()[1:] # split, remove "DS"
    if keys[0] != "N": # found ID, print with comma
        out.write(" ".join(keys) + ",")
    else: # found name, print and end line
        out.write(" ".join(keys[1:]) + "\n")

Выходной файл будет:

User ID 1,user name 1
User ID 2,user name 2

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

import re
pat_id = re.compile(r"DS\s+(User ID\s+\d+)")
pat_name = re.compile(r"DS\s+N\s+(.+\s+\d+)")
out = open("test.dat", "a")

for line in open("input.dat"):
    match = pat_id.match(line)
    if match: # found ID, print with comma
        out.write(match.group(1) + ",")
        continue
    match = pat_name.match(line)
    if match: # found name, print and end line
        out.write(match.group(1) + "\n")

В обоих приведенных выше примерах предполагается, что «идентификатор пользователя X» всегда стоит перед «N именем пользователя X», следовательно, соответствующие завершающие символы «,» и «\ n».

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

Если вы предоставите больше информации, возможно, мы сможем вам помочь.

4 голосов
/ 01 марта 2011

print добавляет символ новой строки после аргументов, а writelines - нет.Таким образом, вы должны написать так:

file = open(outfile, "a")
file.writelines((i + '\n' for i in findPat1))
file.close()

writelines оператор также может быть записан как:

for i in findPat1:
    file.write(i + '\n')
1 голос
/ 01 марта 2011
FILE.writelines(line)

не добавляет разделители строк.

Просто сделай:

FILE.write(line + "\n")

Или:

FILE.write("\n".join(lines))
0 голосов
/ 01 марта 2011
import re

ch ='''\
DS User ID 1
random garbage
random garbage
DS  N user name 1
random garbage
DS User ID 2
random garbage
random garbage
DS  N user name 2'''

RE = '^DS (User ID (\d+)).+?^DS  N( user name \\2)'

with open('outputfile.txt','w') as f:
    for match in re.finditer(RE,ch,re.MULTILINE|re.DOTALL):
        f.write(','.join(match.groups())+'\n')

EDIT:

заменено

RE = '^DS (User ID \d+).+?^DS  N( user name \d+)'

с

RE = '^DS (User ID (\d+)).+?^DS  N( user name \\2)'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...