Python создает 3 файла из 1 файла на основе строк - PullRequest
0 голосов
/ 25 июня 2018

У меня большой набор данных, который хранится в файле в Linux.Я хотел бы написать скрипт на python, который возьмет этот файл и запишет его в 3 файла, основываясь на первом появлении 3 конкретных строк.

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

Handle: A1
OrgID: AA
Name: Name1

Handle: A2
OrgID: BB 
Name: Name2

OrgID: 1111
OrgName: Name1
Street: 1111 Street

OrgID: 2222
OrgName: Name2
Street: 2222 Street

NetHandle: Net1
OrgID: AA
Parent: Net1

NetHandle: Net2
OrgID: BB
Parent: Net2

Я хочу, чтобы в первом файле были все записи, начинающиеся с «Обрабатывать» и заканчивающиеся перед записями, начинающимися с OrgID. Второй файл, содержащий записи, начинающиеся с «OrgID», и третий файл, начинающийся с «NetHandle».Сложность в том, что OrigID есть во всех трех. Я пробовал несколько способов из примеров на стеке и других сайтах, но пока не смог этого сделать. Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 25 июня 2018

Предполагая, что вы разместили буквальный формат файла, самое простое, что нужно сделать - это прочитать куски по 4 строки за раз и переключиться на первую строку. 1


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

with open('dataset.txt', 'r') as f:
    # Create a list with 4 references to the same iterator.
    iters = [iter(f)] * 4
    # Zip into an iterator that grabs one value from each reference.
    chunks = zip(*iters)
    # Now each chunk is a tuple of four successive values.
    for chunk in chunks:

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

outfiles = {'Handle': handles, 'OrgID': orgs, 'NetHandle': nets}

… затем просто извлечь метку из каждого чанка и найти выходной файл:

firstline = chunk[0]
label = firstline.split(':')[0]
outfile = outfiles[label]

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


это вместе:

with open('dataset.txt', 'r') as f, open('handles.txt', 'w') as handles, \
      open('orgs.txt', 'w') as orgs, open('nets.txt', 'w') as nets:
    outfiles = {'Handle': handles, 'OrgID': orgs, 'NetHandle': nets}
    for chunk in zip(*([iter(f)]*4)):
        label = chunk[0].split(':')[0]
        outfiles[label].writelines(chunk)

Или, если вы используете рецепт grouper (который вы должны):

with open('dataset.txt', 'r') as f, open('handles.txt', 'w') as handles, \
      open('orgs.txt', 'w') as orgs, open('nets.txt', 'w') as nets:
    outfiles = {'Handle': handles, 'OrgID': orgs, 'NetHandle': nets}
    for chunk in grouper(f, 4):
        label = chunk[0].split(':')[0]
        outfiles[label].writelines(chunk)

Если файл на самом деле не заканчивается вНовая строка, последний кусок потерпит неудачу.Но это легко исправить, указав '' как fillvalue:

    for chunk in grouper(f, 4, ''):

1.Вы можете сделать вещи чуть более эффективными - хотя и не такими простыми - если предположите, что сначала идут все чанки Handle, затем все чанки OrgID, а затем все чанки NetHandle.Но когда я спросил, было ли это правдой, вы просто ответили: «Они все кусками», и это ничего не решает.Итак, я напишу это, чтобы учесть вероятность того, что они смешаны.

2.Если вы ошибаетесь, и один из кусков начинается с 'Spam:', вы получите KeyError: 'Spam'.Или, если один из чанков не имеет длины в 4 строки, так что в итоге вы выйдете из синхронизации и прочитаете Street: в качестве первой строки, вы получите KeyError: 'Street'.Таким образом, любой неожиданный ввод должен быть легко отлажен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...