Вырезать блок текста из файла в новый файл - PullRequest
0 голосов
/ 28 января 2020

Мне нужна помощь в извлечении блоков текста из файла в отдельные файлы.

Пример:

ltm data-group internal /Common/www_web {
    records {
        /images { }
        /images/ { }
        /test/common/ { }
    }
    type string
}
ltm monitor http /Common/data {
    adaptive disabled
    defaults-from /Common/http
    destination *:*
    interval 1
    ip-dscp 0
    recv "\{\"status\":\"UP\""
    recv-disable "\{\"status\":\"DOWN\""
    send {}
    time-until-up 0
    timeout 4
}
ltm profile http /Common/stage {
    adaptive disabled
    defaults-from /Common/http
    destination *:*
    interval 5
    ip-dscp 0
    recv "\{\"status\":\"UP\""
    recv-disable "\{\"status\":\"DOWN\""
    send "GET /proxy/test HTTP/1.1\r\nHost: staging\r\nConnection: close\r\n\r\n"
    time-until-up 0
    timeout 16
}

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

ltm data-group internal /Common/www_web {
    records {
        /images { }
        /images/ { }
        /test/common/ { }
    }
    type string
}

в отдельный файл.

ltm monitor http /Common/data {
    adaptive disabled
    defaults-from /Common/http
    destination *:*
    interval 1
    ip-dscp 0
    recv "\{\"status\":\"UP\""
    recv-disable "\{\"status\":\"DOWN\""
    send {}
    time-until-up 0
    timeout 4
}

и выше блок в отдельный блок и так далее. До сих пор я пытаюсь найти регулярное выражение для выполнения sh этого и вот мой код:

#!/usr/bin/python
import sys
import re
with open(sys.argv[1], 'r') as f:
    contents = f.read()

regex = ur"(^ltm[\s\S]+^ltm)"
matches = re.search(regex, contents, re.MULTILINE)

if matches:
    print ("{match}".format(start = matches.start(), end = matches.end(), match = matches.group()))

Пока что это регулярное выражение захватывает все с помощью текста 'ltm'. Любая помощь будет оценена.

Я посмотрел на это Извлечение блока текста из файла с использованием python, но в моем случае это мало помогло.

Ответы [ 2 ]

0 голосов
/ 28 января 2020

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

def save_file_name(val):
    """returns a file named after the block count"""
    return f'block_{val}.txt'

# opens and stores said file.
file = open('ltm.txt', 'r')

# starting count.
count = 0

# The file that will contain each block.
new_file = open(save_file_name(str(count)), 'w')

# As @Olvin Roght had pointed out, its better to read
# the file line by line in this fashion.
for line in file:
    # The part that scans for the wanted keyword.
    if line.startswith('ltm'):
        # If True will fire this set of code.
        # add one to count.
        count += 1
        # Close the now finished file.
        new_file.close()
        # create and store a new file.
        # Important to note to turn count into a string
        new_file = open(save_file_name(str(count)), 'w')
        # write the line to the file.
        new_file.write(line)
    else:
        # And If not the wanted keyword, just write
        # to the still open file
        new_file.write(line)

# Always remeber to close the files that you open.
new_file.close()
file.close()
0 голосов
/ 28 января 2020

Вы можете использовать re.split() с простым пониманием списка:

blocks = ["ltm " + s for s in re.split("^ltm ", contents)[1:]]

Также вы можете использовать это регулярное выражение с re.finditer() (но это будет гораздо менее эффективно) :

blocks = [match.group(0) for match in re.finditer("^ltm ((?!^ltm ).)*", contents, re.DOTALL)]

или это с re.findall():

blocks = re.findall("(^ltm ((?!^ltm ).)*)", contents, re.DOTALL)

Вы также можете добиться того же без регулярных выражений, используя str.find() (клон str.index(), который не выдает исключение в случае, если подстрока не найдена) :

delimiter = "ltm "
blocks = []
index = contents.find(delimiter)
while index >= 0:
    new_index = contents.find(delimiter, index + 1)
    if not index or contents[index - 1] in {"\r", "\n"}:
        blocks.append(contents[index: new_index] if new_index > 0 else contents[index: ])
    index = new_index
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...