我有一个典型的.json文件,例如Chef servername.json
{
"name": "myserver123",
"chef_environment": "test",
"run_list": [
"role[base-pkg]",
"role[interesting_stuff]",
"role[user_apps]"
]
}
我想要做的是在文件中找到最后一个角色后使用“一行”来添加新角色。因为我从来不知道文件中有什么角色或有多少我想要搜索最终关闭的"]"
括号并添加上面的新角色。
我尝试了以下方法:
tac servername.json | sed -i '0,/\]/a "role[My_New_Role]"'
认为这会找到(现在)第一个“]”并在其后添加新行。但是,当我运行cmd时,它会添加“role [My_New_Role]”行3次。在"]"
前两次,在"]"
后一次在正确的位置
问题:
1)当“0”表示匹配一次时,为什么该行加3次?
2)使用AWK,Perl或Python(2.7.5)可以做得更好吗?怎么样 ?
3)我应该使用正则表达式前瞻/后面而不是tac吗?
4)因为我需要再次处理文件以向倒数第二个角色添加逗号我的整个方法是错误的吗?什么是更好的方法?
我不知道这是否是最好的方法(vs sed,AWK或Perl),但使用python的json
库可以直截了当地进行操作。
import json
# read the file as a dict using json.loads
d = json.loads(open('servername.json', 'r').read())
# add your new role to the end of the run_list
d['run_list'].append('role[My_New_Role]')
# write new json to file (specify a new file, or overwrite if you prefer)
open('new_servername.json', 'w').write(json.dumps(d, indent=2))
输出文件如下所示:
{
"chef_environment": "test",
"name": "myserver123",
"run_list": [
"role[base-pkg]",
"role[interesting_stuff]",
"role[user_apps]",
"role[My_New_Role]"
]
}
将此代码修改为脚本并将文件名作为输入非常容易,因此可以轻松运行多次。
使用JSON
模块的Perl:
cat servername.json | perl -MJSON -0 -ne '$j = decode_json($_); push @{$j->{run_list}}, q<role[My_New_Role]>; print encode_json($j)'
你可以用print to_json($j, {pretty => 1})
替换print命令来打印它