Есть ли способ поменять две строки текста в текстовом файле с помощью Python? - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь написать скрипт на python, который будет принимать файл (назовем его input.txt) и искать строку, которая заканчивается текстом «перейти к первой точке периметра». Затем необходимо заменить эту строку на следующую после нее строку и заменить следующую строку первой строкой. Остальная часть файла должна быть неизменной. Есть множество случаев, когда это должно происходить в файле.

Мой мыслительный процесс был таким. Ищите линию, которая заканчивается «перейти к первой точке периметра». Как только код найдет его, он сохранит строку как переменную, а затем удалит строку из файла. Затем, если следующая строка заканчивается «восстановить слой Z» (что всегда будет иметь место со следующей строкой), необходимо добавить ранее удаленную строку после этой строки.

Вот что япытаюсь сделать:

  1. Открыть файл ('input.txt').
  2. Поменять местами каждое вхождение двух последовательных строк, где
    • Первая строкаоканчивается на: 'move to first perimeter point'
    • Вторая строка оканчивается на: 'restore layer Z'
    • Примечание : известно, что все такие вхождения всегда будут происходить парами (первая-втораялинии размещены последовательно).
  3. Запишите это изменение в новый файл ('output.txt').

Я попытался собрать это вместе, используя python. Я играл с python много лет назад и смутно помню, как им пользоваться. Это бросило ошибку. Вот мой код после внесения исправлений, предложенных в разделе комментариев: (a) str.endwith --> str.endswith, (b) For --> for. Любые предложения будут очень полезны и приветствуются.

inp = open('input.txt','r')
out = open('output.txt', 'w')
prev = inp.readline()
for line in inp:
    if line.endswith('move to first perimeter point')
        prev = line
        if line.endswith('restore layer Z')
            out.write(line)
            out.write(prev)
    else:
        out.write(prev)
    prev = line
out.write(prev)
out.close()
inp.close

Я ожидал, что входной файл останется неизменным, пока создается новый выходной файл. Вместо этого ничего не произошло.

Спасибо за вашу помощь заранее! Я очень новичок в этом.

1 Ответ

0 голосов
/ 06 ноября 2019

Решение

Здесь мы читаем строки из файла txt в переменную s (список строк). Затем пользовательская функция swap_lines_in_text() выполняет обмен и возвращает кадр данных df для дальнейшей обработки (при необходимости). Наконец, вы можете преобразовать его в список строк, используя df.Text.tolist(), и записать его в новый файл с file.writelines(), как показано ниже.
Поскольку образец данных не был предоставлен, я создал свои собственные (см. Фиктивные данные ниже). Для тестирования решения я буду использовать фиктивные данные.

# Read-in the lines from input file
with open('input.txt', 'r') as f:
    s = f.readlines()

# Execute Swap
df = swap_lines_in_text(s, 
                        first_line_text = 'move to first perimeter point', 
                        second_line_text = 'restore layer Z')

# Show output (comment out the following line if need be)
# print(df)
print('\n'.join(df.Text.tolist()))

# Write to output file
with open('output.txt', 'w') as f:
    f.writelines(df.Text.tolist())

Вывод :

A
B
D restore layer Z
C move to first perimeter point
E
F
H restore layer Z
G move to first perimeter point
I
K restore layer Z
J move to first perimeter point
L
M
N

Пользовательская функция для обработки текста (свопирование целевых строк)

Эта функция будетвернуть pandas.DataFrame объект.

import pandas as pd

def swap_lines_in_text(s, first_line_text='move to first perimeter point', second_line_text='restore layer Z'):
    """
    s = string or a list of strings.
    """
    if isinstance(s, list):
        lines = s.copy()
    else:
        lines = s.strip().split('\n')
    df = pd.DataFrame({'Text': lines})
    df.Text = df.Text.str.strip()
    # Detect Target Lines (both first and second kinds)
    first_lines = df.Text.str.contains(first_line_text)
    second_lines = df.Text.str.contains(second_line_text)
    # Swap lines
    df.Text.loc[first_lines], df.Text.loc[second_lines] = df.Text[second_lines].tolist(), df.Text[first_lines].tolist()
    return df

Фиктивные данные

s = """
A 
B 
C move to first perimeter point 
D restore layer Z
E 
F 
G move to first perimeter point
H restore layer Z
I 
J move to first perimeter point
K restore layer Z
L 
M 
N
"""
print(s.strip())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...