简体   繁体   中英

Parse and Replace String in YAML

I need to replace every occurance of a string in the YAML by another string in Python.

name: responses
new:
    sources:
    - table: response
      source: xxx
      tier: raw
      view: vresponses
      columns:
      - a
      - b
      - c
      - d
      - eff_dt

    extracts:
    - sql: >-
        CREATE or REPLACE TEMPORARY VIEW sql1
        AS
        SELECT distinct
         some_cols,
         {{ place-holder }}
        FROM
        vresponse AS RES
        inner JOIN tab2 AS SUR
        ON RES.SrveyId = SUR.SrveyId

    - sql: >-
        CREATE or REPLACE TEMPORARY VIEW sql1
        AS
        SELECT distinct
         some_cols2,
         {{ place-holder }}
        FROM
        vresponse2 AS RES
        inner JOIN tab3 AS SUR
        ON RES.x = SUR.y

From the above example I want to iterate through all the occurances of -sql key and replace all occurances of the text {{ place-holder }} in all the sql statements present under the -sql key and replace them with a new value.

I have tried this but results in the following error:

>>> input_file = "my_file.yaml"
>>> data = yaml.load(open(input_file))
>>> i = 0
>>> for k, v in data['new']['extracts'][i]:
...     val = v.replace('{{ place-holder }}', 'new_str')
...     print(val)
...     i = i + 1
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack

Once replaced, I want to dump the contents back into yaml format. I am new to Python and YAML. Can anyone please help.

Thanks

If you want to dump the content back into yaml, the easier may be just to read the file line by line, replacing {{ place-holder }} with its new value whenever you encounter it.

input_file = "my_file.yaml"
output_file = "out.yaml"
with open(input_file, "r") as f_in:
    with open(output_file, "w") as f_out:
        for line in f_in:
            line.replace("{{ place-holder }}", "new_str")
            output_file.write(line)

If you want to be sure that your "{{ place-holder }}" string lies within a -sql key block, then you do as you try. You get an Error because when iterating on the (key, value) of a dictionary, you need to use the items() function:

for k, v in data["new"]["extracts"][i].items():

Hope this answers your question.

NB: It is a good practise to open your files in a with block so that they are automatically closed when exiting from the block or in case of error.

Adding on previous response, if you like to pass extracts you should iterate over them with a separate for :

for extract in data["new"]["extracts"]:
    for k,v in extract.items():
        val = v.replace('{{ place-holder }}', 'new_str')
        print(val)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM