我需要编辑特定文件才能进行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”字符串。这是更好的方法吗?我从来没有尝试过,所以一些示例代码将不胜感激。
非常感谢大家!
答案 0 :(得分:0)
当您遍历各行时,所获得的是原始行的副本。
您可以做的就是这样,将文件的内容分成多个部分。由于文件中的每个部分都以########结尾,因此我们可以使用它来将文件拆分为多个块。然后,您可以更改找到的块并将其写回到文件数据中,然后再保存。
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))
答案 1 :(得分:0)
您绝不会为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())
要真正读/写文件,您必须使用{p>更改with
行
with open(newfolder2+'/walls.in','r') as infile,
open(newfolder2+'/walls.out','w') as outfile:
,然后删除包含outfile.getvalue()
的行。然后必须将walls.out
重命名为walls.in
。这样,如果程序执行了您不想要的操作,您的原始文件就不会丢失。
如果您想为其他Wall
更改其他行,这可能很容易适应。
答案 2 :(得分:0)
这里发生了两个错误。
>>> 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]
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
。它应该快得多。如果要在适当的位置修改文件,另请参见Is it possible to modify lines in a file in-place?。