【问题标题】:Is there a way to swap two lines of text in a text file using python?有没有办法使用python交换文本文件中的两行文本?
【发布时间】:2020-03-02 09:44:23
【问题描述】:

我正在尝试编写一个 python 脚本来获取一个文件(我们称之为input.txt),并寻找以文本“移动到第一个周边点”结尾的行。然后它需要将这一行替换为它后面的行,并将它后面的行替换为第一行。文件的其余部分必须保持不变。在文件中需要发生这种情况的情况很多。

我的思考过程是这样的。寻找以“移动到第一个周边点”结尾的线。一旦代码找到它,它将将该行保存为变量,然后从文件中删除该行。然后,如果下一行以“restore layer Z”结尾(下一行总是如此),则需要在此行之后添加先前删除的行。

这是我想要做的:

  1. 打开一个文件 ('input.txt')。
  2. 交换每个出现的两个连续行,其中,
    • 第一行结束于:'move to first perimeter point'
    • 第二行结束于:'restore layer Z'
    • 注意:众所周知,所有此类事件总是成对发生(第一到第二行连续放置)。
  3. 将此更改写入新文件 ('output.txt')。

我曾尝试使用 python 将其组合在一起。几年前玩过python,依稀记得怎么用。它抛出了错误。这是我在 cmets 部分建议更正后的代码:(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

我希望输入文件保持不变,同时创建了一个新的输出文件。相反,什么也没发生。

提前感谢您的帮助!我对此很陌生。

【问题讨论】:

  • 我本来希望看到一条错误消息。也许你根本没有运行它?
  • 我强烈建议您使用 readlines/writelines 函数,它可以让您将文件的行作为数组来处理。 python-reference.readthedocs.io/en/latest/docs/file/…
  • 除了明显的错误(即For而不是forendwith而不是endswith等),当你使用for line in fp时,这些行有一个尾随换行符。所以line.endswith('hello') 永远不会是真的;请改用line.endswith('hello\n')
  • 我对问题进行了建议的更改,试图使其更加客观。一旦,它被接受,请看看它。 @EliteAnorak 请尽量使您的问题结构合理。此外,使用 cmets 部分的建议更新问题是一种很好的做法。这有助于人们理解您的要求,并且人们可能会发现它在未来很有用,并且也会对您的问题进行投票:这反过来会增加您的 stackoverflow 声誉点。此外,结构良好、可重复性极少的问题会很快吸引多个答案。最好的。

标签: python pandas text-files swap text-processing


【解决方案1】:

解决方案

在这里,我们将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())

【讨论】:

  • @EliteAnorak 请尝试该解决方案并让我知道它是否适用于 (1) 虚拟数据,(2) 您的输入文本文件。谢谢。
  • 已修复。请立即检查。
  • @EliteAnorak 如果有帮助,请考虑 acceptingvoting up 解决方案。谢谢你。 注意:当您接受解决方案时,它的旁边会有一个绿色勾号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 2019-02-11
  • 1970-01-01
  • 2021-03-20
  • 2022-11-22
相关资源
最近更新 更多