繁体   English   中英

字符串替换未写入文件

[英]String Replacement Not Being Written to File

我需要为DoE研究编辑某个文件。 该文件的格式为:

1 Wall1
roughness 0.0
velocity 0.0
temperature "temperature.file"
########
2 Wall2
roughness 0.0
velocity 0.0
temperature "temperature.file"
########
3 Wall3
roughness 0.0
velocity 0.0
temperature "temperature.file"
########
4 Wall4
roughness 0.0
velocity 0.0
temperature 34.1
########
5 Roof
roughness 0.0
velocity 0.0
temperature "temperature.file"
########

对于DoE,我想为每种情况更改一个或多个“temperature.file”条目(这是一个区域的空间变化的温度场)。 例如,案例2将Wall2的温度文件更改为“temperature2.file”。 然后程序将知道找到新文件而不是原始文件。

我已经建立了嵌套for循环,但在文件I / O上苦苦挣扎。 我现在的代码是:

if m == 2:
    with open(newfolder2+'/walls.in','r') as file:
        filedata = file.readlines()
        for line in filedata:
            if 'Wall2' in line:
                for line in filedata:
                    if 'temperature' in line:
                        print line
                        line = line.replace('temperature.file','temperature2.file')
                        print line
                        break
#       file.seek(0)

    with open(newfolder2+'/walls.in','w') as file:
        file.writelines(filedata)

所以基本上我想找到发生“Wall2”的行,然后在Wall2之后寻找带温度的行,然后改变它,只将该行的“temperature.file”字符串改为“temperature2.file”。 然后退出该文件,然后写入该文件,从而为该特定情况创建新的输入文件。

我的第一条打印线确实打印出原始行,第二条打印行代码也正确地打印出更改的行。 但是,似乎文件数据没有成功写回文件。

什么似乎出错了?

我想,另一种方法,而不是所有嵌套循环来找到特定的行,只是使用file.seek()选项。 wall.in文件中的行和总长度将保持不变,因此我可以直接转到该特定行来更改“temperature.in”字符串。 这是一种更好的方法吗? 我从来没有试过这个,所以一些示例代码将非常感激。

非常感谢你们!

当您遍历这些行时,您获得的是原始行的副本。

你可以做的就是这样你将文件的内容分成几块。 由于文件中的每个部分都以########结尾,我们可以使用它将文件拆分为块。 然后,您可以在保存之前更改找到的块并将其写回filedata。

with open(newfolder2+'/walls.in', 'r') as file:
filedata = file.read().split("########")
for i, chunk in enumerate(filedata):
    if "Wall2" in chunk:
        chunk = chunk.replace('temperature.file', 'temperature2.file')
        filedata[i] = chunk

with open(newfolder2+'/walls.in', 'w') as file:
    file.writelines("########".join(filedata))

你永远不会给你的filedata分配任何新东西。

你可以写一些类似于知道上下文的解析器(这里:你所在的墙号)。 这可能看起来像这样:

from io import StringIO

# thie u is needed in python < 3
txt = u"""1 Wall1
roughness 0.0
velocity 0.0
temperature "temperature.file"
########
2 Wall2
roughness 0.0
velocity 0.0
temperature "temperature.file"
########
"""

wall = None
with StringIO(txt) as infile, StringIO() as outfile:
    for line in infile:
        if " Wall" in line:
            wall = int(line[:2])
        if wall == 2:
            if '"temperature.file"' in line:
                line = line.replace('"temperature.file"', '"temperature2.file"')
        outfile.write(line)

    print(outfile.getvalue())

要真正读/写你的文件你必须改变with

with open(newfolder2+'/walls.in','r') as infile, 
     open(newfolder2+'/walls.out','w') as outfile:

并删除包含outfile.getvalue() 然后你必须将walls.out重命名为walls.in 这样,如果程序执行了您不想要的操作,原始文件不会丢失。

如果你想改变其他Wall的其他线路,这可能很容易适应。

这里发生了两个错误。

  1. 当您在for循环中进行迭代时,更改变量将在本地初始化,并且更改它实际上不会更改循环的对象。
>>> a = [5,4,3,7,1]
>>> for i in a:
...     i=2  # this won't change the elements of a!
... 
>>> a
[5, 4, 3, 7, 1]
  1. 你有结构化的方式,第二个for循环会遍历filedata从发现后非常再次开始Wall2 这是因为for循环本身并不知道它正在另一个for循环中运行。 即使你修复了1,你最终也会得到错误的结果。要么使用迭代器来遍历filedata要么使用f.readline()这是一个生成器本身。
filedata=iter(filedata)

以下代码应该有效:

filedata = []
with open('myfile') as f:
    line = ''
    while 'Wall2' not in line:
        line = f.readline()
        filedata.append(line)
    while 'temperature' not in line:
        line = f.readline()
        filedata.append(line)
    filedata.append(line.replace('temperature.file','temperature2.file'))

with open('myfile', 'w') as f:
    f.writelines(filedata)

但是,我不会这样做。 如果您知道文件始终采用相同的格式且行号始终保持不变,请使用file.seek 它应该快得多。 另请参阅是否可以就地修改文件中的行? 如果要修改文件到位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM