文章目录
1 基础知识
2 读取配置文件
3 改写配置文件
3.1 删除section
3.2 字符串大小写问题
4 实例
4.1 1维两层的数据
4.2 多维两层的数据
4.3 使用am运行得到的文件
参考文献:
【1】 python读取配置文件&&简单封装
【2】 python 中使用ConfigParser类修改配置文件
【3】 python3中的RE(正则表达式)-总结
1 基础知识
python里面需要使用到configparser包,可以使用pip安装
pip install configparser
在配置文件里面,默认使用[ ]表示section,如下config.ini文件表示有两个节:
[user1]
user_ip = 127.0.0.1
user_name = testuser1
user_id = 45
[user2]
user_ip = 127.0.0.2
user_name = testuser2
user_id = 41
2 读取配置文件
下面代码有注释,关于使用os写相对路径,可以看参考文献【1】
import configparser
cf = configparser.ConfigParser()
cf.read("config.ini") # 读取配置文件,如果写文件的绝对路径,就可以不用os模块
secs = cf.sections() # 获取文件中所有的section(一个配置文件中可以有多个配置,如数据库相关的配置,邮箱相关的配置,
# 每个section由[]包裹,即[section]),并以列表的形式返回
print(secs)
options = cf.options("user1") # 获取某个section名为user1所对应的键
print(options)
items = cf.items("user1") # 获取section名为user1所对应的全部键值对
print(items)
name = cf.get("user1", "user_name") # 获取user1中user_name对应的值
print(name)
3 改写配置文件
已知原始config.ini文件如下
[user1]
user_ip = 127.0.0.1
user_name = testuser1
user_id = 45
[user2]
user_ip = 127.0.0.2
user_name = testuser2
user_id = 41
写一个write_config.py来更改配置文件
import configparser
import numpy as np
import copy
conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)
node = "user1" #改user1
key = "user_id"
value = "00"
conf.set(node, key, value)
fh = open(filename, 'w')
conf.write(fh) # 把要修改的节点的内容写到文件中
fh.close()
更新:
上面的写入文件代码
fh = open(filename, 'w')
conf.write(fh) # 把要修改的节点的内容写到文件中
可能在某些文件中最后一行会有问题,所以将之改为(下面所有代码都这么改即可)
with open('config.txt', 'w') as configfile:
conf.write(configfile)
运行此文件之后,发现配置文件变了
[user1]
user_ip = 127.0.0.1
user_name = testuser1
user_id = 00 #改为00
[user2]
user_ip = 127.0.0.2
user_name = testuser2
user_id = 41
使用for循环将两个user同时改
import configparser
import numpy as np
import copy
conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)
secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']
ip_key = 'user_ip'
name_key = 'user_name'
id_key = 'user_id'
for i in range(len(secs)):
conf.set(secs[i], ip_key,user_ip[i])
conf.set(secs[i], name_key, user_name[i])
conf.set(secs[i], id_key, user_id[i])
fh = open(filename, 'w')
conf.write(fh)
fh.close()
当然,conf.set可以直接指定字段,不用重命名
import configparser
import numpy as np
conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)
secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']
for i in range(len(secs)):
conf.set(secs[i], 'user_ip', user_ip[i])
conf.set(secs[i], 'user_name', user_name[i]) #直接指定字段
conf.set(secs[i], 'user_id', user_id[i])
fh = open(filename, 'w')
conf.write(fh)
fh.close()
结果为
[user1]
user_ip = 192.168.0
user_name = python
user_id = 111
[user2]
user_ip = 192.168.1
user_name = python1
user_id = 222
以上都是没有写成类的,要写成类的形式可以看参考文献【1】
3.1 删除section
config.remove_option('user1', 'user_ip')# 删除user1分组的user_ip
config.remove_section('user1')# 删除配置文件中user1分组(会将整个user1下的ip,id,name都删除)
更多关于config的使用可以看官网
现在有另一个需求:将修改后的配置文件保存到一个名为config.txt的文件中,并去掉中括号内的字符,即去掉[user1],[user2]
上面的代码,实际上修改完之后通过open可以写入到新文件中(原文件的内容不会改变)
for i in range(len(secs)):
conf.set(secs[i], 'user_ip', user_ip[i])
conf.set(secs[i], 'user_name', user_name[i]) #直接指定字段
conf.set(secs[i], 'user_id', user_id[i])
#fh = open(filename, 'w')
fh = open('config.txt','w') #文件另存到config.txt中
conf.write(fh)
fh.close()
现在需要将[user1],[user2]字段去掉,一个方法是将它们替换为空。比如这里将[user2]改为空,即``,注意不是表示的空格,而是none。
import configparser
import numpy as np
conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)
secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']
for i in range(len(secs)):
conf.set(secs[i], 'user_ip', user_ip[i])
conf.set(secs[i], 'user_name', user_name[i]) #直接指定字段
conf.set(secs[i], 'user_id', user_id[i])
#fh = open(filename, 'w')
fh = open('config.txt','w') #文件另存到config.txt中
conf.write(fh)
fh.close()
#将[user2]去掉
with open('config.txt', 'r') as fpr:
content = fpr.read()
content = content.replace('[user2]', '')
with open('config.txt', 'w') as fpw: #如果要另存为a.txt,则将config.txt改为a.txt
fpw.write(content)
结果如下
另外,可以使用正则表达式
import re
# read file
f1 = open('config.txt','r')
f2 = open('a.txt','w')
# write file
for ss in f1.readlines():
a = re.sub(r'\[user2\]','',ss)
f2.write(a)
f1.close()
f2.close()
上面需要注意,正则表达式如果没有斜杠,\[user\],会表示将所有的user都换掉,包括user_id等里面的user字符都去掉。那么既然使用了正则表达式,就可以将user1,user2同时去掉了,可以规定但凡有[user*的都去掉(*表示后面所有)或者但凡user后有数字接着的都去掉。这部分可以看参考文献【3】
所以只需要将上面的代码改为:
# read file
f1 = open('config.txt','r')
f2 = open('a.txt','w')
# write file
for ss in f1.readlines():
a = re.sub(r'\[user\d\]','',ss) #\d表示匹配0-9数字
f2.write(a)
f1.close()
f2.close()
结果为
至此,完整代码如下:
import configparser
import numpy as np
import re
conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)
secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']
for i in range(len(secs)):
conf.set(secs[i], 'user_ip', user_ip[i])
conf.set(secs[i], 'user_name', user_name[i]) #直接指定字段
conf.set(secs[i], 'user_id', user_id[i])
with open('config.txt', 'w') as configfile:
conf.write(configfile)
configfile.close()
# read file
f1 = open('config.txt','r')
f2 = open('a.txt','w')
# write file
for ss in f1.readlines():
a = re.sub(r'\[user\d\]','',ss)
f2.write(a)
f1.close()
f2.close()
3.2 字符串大小写问题
源包configparser中设置的输出都是小写的,比如把上面例题中的user_ip改为User_ip,即首字母大写,结果运行完之后得到的却依然是user_ip这是因为在configparser包中定义的输出为小写
def optionxform(self, optionstr):
return optionstr.lower() #转小写字母
因此我们可以自己写一个函数,替换掉optionxform,即
import configparser
class Myconf(configparser.ConfigParser):
def __init__(self, defaults=None):
configparser.ConfigParser.__init__(self, defaults=None) #继承父类
def optionxform(self, optionstr):
return optionstr #没有改为小写
conf = Myconf()
4 实例
这是本人需要解决的一个问题,不感兴趣的读者可以不往下看了,仅作为笔者笔记使用
4.1 1维两层的数据
相当于望远镜只朝天上看一个方向,这个方向上把水汽分成两层,每层得到一组数据
即数据如下:
Pbase = ['542', '542']
Tbase = ['268.6', '268.6']
column_h2o_vmr = ['5.49e-04', '5.49e-04']
column_o3_vmr = ['4.38e-08', '4.38e-08']
具体过程如下:
现在有一个名为onelayer.amc的文件
既
? Example:
? am test.amc 0 GHz 300 GHz 10 MHz 0 deg
?
f %1 %2 %3 %4 %5 %6
output f GHz Tb K
jacobian Tb
za %7 %8
tol 1e-4
Nscale troposphere h2o 1.0
T0 2.7 K
layer troposphere
Pbase 542 mbar
Tbase 368.6 K
column dry_air vmr
column h2o vmr 5.49e-04
column o3 vmr 4.38e-08
layer troposphere
Pbase 542 mbar
Tbase 368.6 K
column dry_air vmr
column h2o vmr 5.49e-04
column o3 vmr 4.38e-08
现在需要对其修改layer troposphere下面的Pbase,Tbase等参数,使用configparser。(我相信肯定有更好的办法,欢迎留言)
首先要修改onelayer.amc文件到config.ini中,如下(注意配置文件一定是xx=yy的形式,没有=会报错的,所以临时修改了一些量,使得都含有=号,最后再想办法用正则表达式去掉=号即可)
[layer 2]
layer=troposphere
Pbase=542 mbar
Tbase=268.6 K
column_dry_air=vmr
column_h2o_vmr=5.49e-04
column_o3_vmr=4.38e-08
[layer 1]
layer=troposphere
Pbase=542 mbar
Tbase=268.6 K
column_dry_air=vmr
column_h2o_vmr=5.49e-04
column_o3_vmr=4.38e-08
然后在需要最后写入的文件a.txt中将前面部分不需要改动的写进去,之后在写入每个layer troposphere的时候通过追加的形式。
? Example:
? am test.amc 0 GHz 300 GHz 10 MHz 0 deg
?
f %1 %2 %3 %4 %5 %6
output f GHz Tb K
jacobian Tb
za %7 %8
tol 1e-4
Nscale troposphere h2o 1.0
T0 2.7 K
所以所有的文件大概关系是
运行write_config.py得到a.txt文件为:
源码如下
import configparser
import numpy as np
import re
class Myconf(configparser.ConfigParser):
def __init__(self, defaults=None):
configparser.ConfigParser.__init__(self, defaults=None)
def optionxform(self, optionstr):
return optionstr
conf = Myconf()
filename = "config.ini"
conf.read(filename)
secs = conf.sections()
Pbase = ['542', '542']
Tbase = ['268.6', '268.6']
column_h2o_vmr = ['5.49e-04', '5.49e-04']
column_o3_vmr = ['4.38e-08', '4.38e-08']
for i in range(len(secs)):
conf.set(secs[i], 'Pbase', Pbase[i]+' mbar') #加入单位mbar
conf.set(secs[i], 'Tbase', Tbase[i]+' K') #直接指定字段
conf.set(secs[i], 'column_h2o_vmr', column_h2o_vmr[i])
conf.set(secs[i], 'column_o3_vmr', column_o3_vmr[i])
#文件另存到config.txt中
with open('config.txt', 'w') as configfile:
conf.write(configfile)
configfile.close()
# read file
f1 = open('config.txt','r')
f2 = open('a.txt','a') #追加的形式
# write file
for ss in f1.readlines():
ss = re.sub(r'\[layer \d\]','',ss)
ss = re.sub('layer = troposphere', 'layer troposphere',ss)
ss = re.sub(r'base =',r'base',ss)
ss = re.sub('column_dry_air = vmr', 'column dry_air vmr',ss)
ss = re.sub('column_h2o_vmr =', 'column h2o vmr', ss)
ss = re.sub('column_o3_vmr =', 'column o3 vmr', ss)
f2.write(ss)
f1.close()
f2.close()
4.2 多维两层的数据
相当于望远镜只朝天上看一个方向,这个方向上把水汽分成两层,每层得到一组数据;然后移动望远镜一定的距离又得到另一个方向上的数据。
Pbase = [['542', '500'],['530','480']] #二维数据,每个维度表示一个方向上的点
Tbase = [['268.6','250'], ['265','258']]
column_h2o_vmr = [['5.49e-04','5.41e-04'], ['5.43e-04','5.40e-04']]
column_o3_vmr = [['4.4e-08','4.3e-08'],['4.50e-08', '4.38e-08']]
1
2
3
4
具体过程如下:
我们现在要把每个方向上观测到的点放入单个文件中,即一个文件表示一个方向。
首先我们要把前缀部分统一写入多个文件,以两个方向为例,即两个文件
先建立一个只有前缀的prefix.amc文件
将上面的文件写入每个文件中,即写入a0.amc, a1.amc中,相当于拷贝
#write prefix to files:
for j in range(len(Pbase)):
prefix_file = open('prefix.amc', 'r')
f0 = open('a'+str(j)+'.amc','w')
text = prefix_file.read()
f0.write(text)
f0.close()
prefix_file.close()
1
2
3
4
5
6
7
8
然后就可以开始上面同样的过程了(这里我把for放一起了),完整代码如下:
import configparser
import numpy as np
import re
class Myconf(configparser.ConfigParser):
def __init__(self, defaults=None):
configparser.ConfigParser.__init__(self, defaults=None)
def optionxform(self, optionstr):
return optionstr
conf = Myconf()
filename = "config.ini"
conf.read(filename)
secs = conf.sections()
Pbase = [['542', '500'], ['530', '480']] # 二维数据,每个维度表示一个方向上的点
Tbase = [['268.6', '250'], ['265', '258']]
column_h2o_vmr = [['5.49e-04', '5.41e-04'], ['5.43e-04', '5.40e-04']]
column_o3_vmr = [['4.4e-08', '4.3e-08'], ['4.50e-08', '4.38e-08']]
#write prefix to files:
for j in range(len(Pbase)):
prefix_file = open('prefix.amc', 'r')
f0 = open('a'+str(j)+'.amc','w')
text = prefix_file.read()
f0.write(text)
f0.close()
prefix_file.close()
for j in range(len(Pbase)):
for i in range(len(secs)):
conf.set(secs[i], 'Pbase', Pbase[j][i]+' mbar') #加入单位mbar
conf.set(secs[i], 'Tbase', Tbase[j][i]+' K') #直接指定字段
conf.set(secs[i], 'column_h2o_vmr', column_h2o_vmr[j][i])
conf.set(secs[i], 'column_o3_vmr', column_o3_vmr[j][i])
#文件另存到config.txt中
with open('config'+str(j)+'.txt', 'w') as configfile:
conf.write(configfile)
configfile.close()
f1 = open('config'+str(j)+'.txt', 'r')
f2 = open('a'+str(j)+'.amc', 'a')
# write file
for ss in f1.readlines():
ss = re.sub(r'\[layer \d\]', '', ss)
ss = re.sub('layer = troposphere', 'layer troposphere', ss)
ss = re.sub(r'base =', r'base', ss)
ss = re.sub('column_dry_air = vmr', 'column dry_air vmr', ss)
ss = re.sub('column_h2o_vmr =', 'column h2o vmr', ss)
ss = re.sub('column_o3_vmr =', 'column o3 vmr', ss)
f2.write(ss)
f2.close()
f1.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
得到两个文件,a1.amc如下
4.3 使用am运行得到的文件
这部分由于要使用am在终端运行,所以得要借助shell命令,
参考shell运行文件
建立一个名为run.sh的文件,内容为:
由于间隔是2GHz,所以只会输出100GHz对于的值
补充:上面的的>表示输出到文件,而如果使用>>则表示追加,即在原文件后累加。
如我将上面的>改为>>,则得到的结果如下:
现在有两个文件a0.amc, a1.amc所以需要使用for循环,参考另一博文
因为采用的是seq这种for循环,必须从1开始(尝试了其他的循环都没有效果)
所以对上面一开始的文件做如下处理:
1)将文件a0.amc改为a2.amc
2)由于am运行的时候底下最低的一层Pbase似乎是要大于550 mbar,所以将值改为大于550的任意值即可
现在开始写run.sh文件
使用追加的形式,将运行结果统一放置在a.out中,运行结束会输出done
运行run.sh,有两种方法
1,直接sh运行
sh run.sh
1
2, 给定权限之后运行
chmod +x run.sh
./run.sh
1
2
得到结果
————————————————
版权声明:本文为CSDN博主「Mr-Cat伍可猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Mr_Cat123/article/details/108982842