Add a new role to a Chef .json file with Sed

混江龙づ霸主 提交于 2019-12-08 08:55:59

问题


I have a typical .json file for Chef e.g. servername.json

{

  "name": "myserver123",

  "chef_environment": "test",

  "run_list": [

    "role[base-pkg]",

    "role[interesting_stuff]",

    "role[user_apps]"


  ]

}

What I would like to do is use a "one liner" to add a new role after the last role found in the file. Since I never know what roles or how many are in a file i thought to search for the final closing "]" bracket and add the new role above that.

I tried the following:

tac servername.json | sed -i '0,/\]/a "role[My_New_Role]"'

thinking that this would find the (now) first "]" and add the new line after it. However when I run the cmd it adds the line "role[My_New_Role]" 3 times. Twice before the "]" and once in the correct place after the "]"

Questions:

1) Why is the line added 3 times when the "0" says match once ?

2) Would this be better done using AWK, Perl or Python (2.7.5) ? How ?

3) Should I use regex lookahead/behind instead of tac ?

4) Since I will need to process the file again to add a comma to the second to last role perhapes my whole approach is wrong ? What would be a better approach ?


回答1:


I don't know if this is the best approach (vs sed, AWK, or Perl) but it is straightforward to do what you're asking using python's json library.

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))

The output file looks like:

{
  "chef_environment": "test", 
  "name": "myserver123", 
  "run_list": [ 
    "role[base-pkg]", 
    "role[interesting_stuff]", 
    "role[user_apps]",
    "role[My_New_Role]"
  ]
}

It's pretty easy to modify this code into a script with the filename as an input so that it's easy to run multiple times.




回答2:


Perl with the JSON module:

cat servername.json | perl -MJSON -0 -ne '$j = decode_json($_); push @{$j->{run_list}}, q<role[My_New_Role]>; print encode_json($j)'

you can pretty-print it by replacing the print command with print to_json($j, {pretty => 1})



来源:https://stackoverflow.com/questions/47893288/add-a-new-role-to-a-chef-json-file-with-sed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!