首页 > 解决方案 > 替换文本文件中的数据/字符串

问题描述

我正在尝试自动化我工作的某些部分。我有一个类似文本的 INP 文件(但不是 .txt 文件)并且包含字符串和整数/浮点数。我想用循环的输出(结果)中的值替换从 6 到结束行的某些列。

这是我想要完成的test.INP

  1. 保留前 5 行,将第 3-5 列的数据替换为结果中的数据。希望最终test.INP文件不是新创建的,但数据已被替换。

  2. 因为要替换的数据的维度和result中的目标数据是一样的,为了避免前5行,我试图定义一个函数来逐行反向读取并替换test.INP文件。

Python脚本:

...
with open('test.INP') as j:
    raw = j.readlines()

    def replace(raw_line, sep='\t', idx=[2, 3, 4], values=result[-1:]):
        temp = raw[-1].split('\t')
        for i, v in zip(idx, values):
            temp[i] = str(v)
        return sep.join(temp)

    raw[::-1] = replace(raw[::-1])

print('\n'.join(raw))
...

test.INP 内容(之前):

aa bb cc dd
abcd
e
fg
cols1   cols2   cols3   cols4   cols5   cols6
65  69  433 66  72  70b
65  75  323 61  71  68g
61  72  12  57  73  26c

结果内容:

[[329   50  58]
 [258   47  66]
[451    38  73]]

我的最终目标是获得test.INP以下内容:

test.INP 内容(之后):

aa bb cc dd
abcd
e
fg
cols1   cols2   cols3   cols4   cols5   cols6
65  69  329 50  58  70b
65  75  258 47  66  68g
61  72  451 38  73  26c

但是代码没有按预期工作,test.INP文件中似乎没有任何变化。有什么建议么?

在底部收到错误消息,它说:

ValueError                                Traceback (most recent call last)
<ipython-input-1-92f8c1020af3> in <module>
     36                 temp[i] = str(v)
     37             return sep.join(temp)
---> 38         raw[::-1] = replace(raw[::-1])
     39 print('\n'.join(raw))

ValueError: attempt to assign sequence of size 100 to extended slice of size 8

标签: pythonpython-3.x

解决方案


我无法理解您的代码,所以我构建了自己的版本。

稍后您会了解您尝试做什么 - 您将行从最后一个反转到工作,直到您使用 all results。问题是您忘记了会执行此操作的循环。您replace只运行一次并一次发送所有行,但replace仅适用于一行并且它只返回一行 - 所以最后你得到一行(有 8 列)并且你想分配所有行的位置(可能是 100 行)


这里版本适合我。我将文本直接放入代码中,但我希望它也适用于文件中的文本

text = '''aa bb cc dd
abcd
e
fg
cols1\tcols2\tcols3\tcols4\tcols5\tcols6
65\t69\t433\t66\t72\t70b
65\t75\t323\t61\t71\t68g
61\t72\t12\t57\t73\t26c'''

results = [[329, 50, 58], [258, 47, 66], [451, 38, 73]]
idx = [2,3,4]
sep = '\t'    

print(text)

#with open('test.INP') as j:
#    lines = j.readlines()
    
# split text to lines    
lines = text.splitlines()

def replace(line_list, result_list, idx):
    for i, v in zip(idx, result_list):
        line_list[i] = str(v)
    return line_list

# start at 5 line and group line (text) with values to replace    
for line_number, result_as_list in zip(range(5, len(lines)), results):
    # convert line from string to list
    line_list = lines[line_number].split(sep)
    
    # replace values
    line_list = replace(line_list, result_as_list, idx)
    
    # convert line from list to string
    lines[line_number] = sep.join(line_list)

# join lines to text
text = '\n'.join(lines)

print(text)

with open('test.INP', 'w') as j:
    j.write(text)

推荐阅读