【问题标题】:Python modify text file by the name of argumentsPython通过参数名称修改文本文件
【发布时间】:2019-03-22 19:43:20
【问题描述】:

我有一个文本文件 ("input.param"),它用作包的输入文件。我需要修改一个参数的值。需要更改的行如下:

param1        0.01
model_name    run_param1

我需要搜索参数param1并修改0.01的值以获得一系列不同的值,同时model_name也将相应地更改为param1的不同值。例如,如果 para1 更改为 0.03,则 model_name 更改为 'run_param1_p03'。以下是我的一些尝试代码:

import numpy as np
import os


param1_range = np.arange(0.01,0.5,0.01)
with open('input.param', 'r') as file :
   filedata = file.read()

for p_value in param1_range:
    filedata.replace('param1        0.01', 'param1        ' + str(p_value))
    filedata.replace('model_name    run_param1', 'model_name    run_param1' + '_p0' + str(int(round(p_value*100))))

   with open('input.param', 'w') as file:
       file.write(filedata)

   os.system('./bin/run_app param/input.param')

但是,这不起作用。我猜主要问题是replace 命令无法识别space。但我不知道如何搜索参数param1model_name 并更改它们的值。

【问题讨论】:

  • 您没有将replaced 文本分配给任何地方。做filedata = filedata.replace(..) 注意:str.replace 不做inplace 替换
  • 你看过正则表达式吗? docs.python.org/3/library/re.html
  • @hansolo 谢谢,这是一个很好的收获。我解决了这个问题并继续努力。
  • @bison 感谢您的建议。我会检查的。

标签: python replace command


【解决方案1】:

我正在编辑此答案以更准确地回答原始问题,但它没有充分做到这一点。

问题是replace 命令无法识别空格”。为此,re 或正则表达式模块可以提供很大帮助。您的文档由一个条目及其值组成,以空格分隔:

param1        0.01
model_name    run_param1

在正则表达式中,一般捕获如下所示:

import re

someline = 'param1        0.01'
pattern = re.match(r'^(\S+)\s+(\S+)$', someline)

pattern.groups()
# ('param1', '0.01')

正则表达式的作用如下:

^ 捕获行首 \Sany 非空格字符,或者,('\t', ' ', '\r', '\n') 中的任何 not + 表示一个或多个为贪婪搜索(将继续前进直到模式停止匹配) \s+any 空白字符(与 \S 相反,请注意此处的大小写) () 表示组,或者您希望如何对搜索进行分组

如果您愿意,这些组使您可以相当轻松地将参数解压缩为变量。将此应用于您已有的代码:

import numpy as np 
import re

param1_range = np.arange(0.01,0.5,0.01)
filedata = []

with open('input.param', 'r') as file:
    # This will put the lines in a list
    # so you can use ^ and $ in the regex
    for line in file:
        filedata.append(line.strip()) # get rid of trailing newlines

# filedata now looks like:
# ['param1        0.01', 'model_name    run_param1']

# It might be easier to use a dictionary to keep all of your param vals
# since you aren't changing the names, just the values
groups = [re.match('^(\S+)\s+(\S+)$', x).groups() for x in filedata]

# Now you have a list of tuples which can be fed to dict()
my_params = dict(groups)
# {'param1': '0.01', 'model_name': 'run_param1'}

# Now just use that dict for setting your params
for p_value in param1_range:
    my_params['param1'] = str(p_value)
    my_params['model_name'] = 'run_param1_p0' + str(int(round(p_value*100)))

    # And for the formatting back into the file, you can do some quick padding to get the format you want
    with open('somefile.param', 'w') as fh:
        content = '\n'.join([k.ljust(20) + v.rjust(20) for k,v in my_params.items()])
        fh.write(content)

填充是使用 str.ljuststr.rjust 方法完成的,因此您会得到如下所示的格式:

for k, v in dict(groups).items():
    intstr = k.ljust(20) + v.rjust(20)
    print(intstr)

param1                              0.01
model_name                    run_param1

如果您愿意,可以忽略rjust

【讨论】:

  • 感谢您的指出。但是程序仍然没有做我想做的事。
  • @HuanianZhang 我已经编辑了我的答案以更好地反映您的问题,希望对您有所帮助
  • 非常感谢。最后我切换到 bash shell 脚本,这似乎更容易进行模式匹配和替换。
猜你喜欢
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
相关资源
最近更新 更多