Вопрос по split, file, python – Как разделить один файл на два с помощью Python? [закрыто]

4

У меня есть файл, содержащий несколько строк кода, а затем шаблон строки. Мне нужно написать все до строки, содержащей шаблон строки в файле один и все после шаблона строки в файле два:

например (Файл-контент)

codeline 1 codeline 2 string pattern codeline 3

Выходными данными должен быть файл один с кодовой строкой 1, кодовой строкой 2 и файл два с кодовой строкой 3.

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

Не могли бы вы привести пример используемого строкового шаблона и кодовой строки? - Это также файл .csv или обычный файл .txt? tabchas

Ваш Ответ

7   ответов
5

Л. & APOS; s но используетitertools потому что это весело.

 dont_break = lambda l: l.strip() != 'string_pattern'

 with open('input') as source:
     with open('out_1', 'w') as out1:
         out1.writelines(itertools.takewhile(dont_break, source))
     with open('out_2', 'w') as out2:
         out2.writelines(source)

Вы можете заменить функцию dont_break регулярным выражением или чем-то еще, если это необходимо.

Это, вероятно, лучшее решение для файлов, которые не помещаются в памяти. Itertools означает, что циклы выполняются на C-стороне, что означает, что они будут быстрее (что может иметь значение, учитывая большое количество строк, которые можно ожидать, если память имеет значение). Я отмечу, что если вы собираетесь определять лямбду отдельно, как это, Вы могли бы также использоватьdef заявление.
+1 для удовольствия.
3
with open('data.txt') as inf, open('out1.txt','w') as of1, open('out2.txt','w') as of2:
    outf = of1
    for line in inf:
        if 'string pattern' in line:
            outf = of2
            continue  # prevent output of the line with "string pattern" 
        outf.write(line)

так как работает построчно. Предполагаетstring pattern происходит только один раз во входном файле. мне нравитсяstr.partition() подходить лучшеif весь файл может поместиться в память (что не может быть проблемой)

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

@Robru я упомянул об использованииcontinue сделатьstring pattern исчезнуть, но, думаю, мне следовало бы прочитать вопрос более внимательно :-) .. Я обновлю свое решение, спасибо.
Закрыть, но я верю, что ваш код приведет к «строковому шаблону» появляется вoutf2когда в вопросе указано, что «строковая структура» должен исчезнуть с выхода. В этом случае просто добавьтеcontinue как следующая строка послеoutf = outf2 и это должно работать.
2

with open('infile') as fp, open('of1','w') as of1, open('of2','w') as of2:
    of1.writelines(iter(fp.readline, sentinel))
    of2.writelines(fp)
Хорошая точка зрения! Я всегда забываю об этой формеiter, Конечно, это работает только для точно известных часовых, а не для регулярных выражений или чего-то подобного.
2

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

inp = open('inputfile')
out = open('outfile1', 'w')
for line in inp:
  if line == "Sentinel text\n":
    out.close()
    out = open('outfile2', 'w')
  else:
    out.write(line)
out.close()
inp.close()
Использоватьwith заявление, где открытие файлов.
1

Вам нужно что-то вроде:

def test_pattern(x):
    if x.startswith('abc'): # replace this with some exact test
        return True
    return False

found = False
out = open('outfile1', 'w')
for line in open('inputfile'):
    if not found and test_pattern(line):
        found = True
        out.close()
        out = open('outfile2', 'w')
    out.write(line)
out.close()

замените строку на начальные с тестом, который работает с вашим шаблоном (при необходимости используйте сопоставление с шаблоном из re, но все, что найдет разделительную линию, подойдет).

@Lattyware: with - это хорошо, но неуместно, так как это относительно новое дополнение к Python, и мы не знаем, какую версию Python использует dom_frank.
Использоватьwith заявление, где открытие файлов.
@Anthon Никто, кто только изучает Python, не будет использовать что-либо до 2.5; если ОП использует 2.5, то ему просто нужно добавитьfrom __future__ import with_statement.
@Sven: спасибо, что заметили опечатки. ИМХО, неподходящий, неуместен, если вы еще не знаете, как именно тестировать, это был просто легко расширяемый пример с провалом в том, чтобы быть ложным. Если тест становится многострочным с другими операторами if, например, найдите первые 2 символа, а затем разделите их на «& apos; |»; и осмотрите следующие два символа, тогда это легче адаптировать.
@Anthon Только то, что что-то новое, не означает, что его следует избегать, кроме того, как говорит Дугал, это отнюдь не новая функция. Это стандарт, и каждый (как должен) использует его. Я считаю, что любой новый код не использует его как неправильный - он приводит к потенциальным ошибкам без причины и снижает читабельность.
2

Наивный пример (который не загружает файл в память, подобную Sven's):

with open('file', 'r') as r:
    with open('file1', 'w') as f:
        for line in r:
            if line == 'string pattern\n':
                break
            f.write(line)
    with open('file2', 'w') as f:
        for line in r:
            f.write(line)

Это предполагает, что'string pattern' происходит один раз во входном файле.

Если шаблон не является фиксированной строкой, вы можете использоватьre модуль.

Использоватьwith заявление, где открытие файлов.
@ Lattyware этоnaive пример :) Кроме того, в этом конкретном случае адаптировать код к использованию сложнее, чем обычноwith.
Вы, кажется, обиделись, если вы знаете, что это лучшая идея, то почему бы не использовать ее? Если вы не хотите давать код без просмотра кода, спросите код у спрашивающего, не дайте ответ, который работает, но имеет скрытые потенциальные ошибки - которые вредны для всех (например, людей, которые могут столкнуться с этим вопросом). ищу ответ позже). Я даю предложение улучшить ответ, который соответствует принципу работы SO. Это не нападение на вас, это попытка улучшить ресурс.
Комментарии не показывают это достаточно ясно. В духе SO я сделал редактирование самостоятельно (и исправил еще одну незначительную ошибку - шаблону нужна новая строка для работы).
А также?with это лучшая практика Нет причин не использовать его. Идея о том, что ее трудно изменить, просто не соответствует действительности, поскольку ее проще использовать и она обеспечивает закрытие файлов, даже в исключительных ситуациях, - то, что ваш код даже не пытается в данный момент.
9

Если входной файл помещается в память, самое простое решение - использоватьstr.partition():

with open("inputfile") as f:
    contents1, sentinel, contents2 = f.read().partition("Sentinel text\n")
with open("outputfile1", "w") as f:
    f.write(contents1)
with open("outputfile2", "w") as f:
    f.write(contents2)

Это предполагает, что вы знаете точный текст строки, разделяющей две части.

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

Похожие вопросы