Search code examples
groovyreplaceall

How to find and replace string using groovy script


I need to search some text from file and replace with other string using Groovy script. I am explaining my file below.

test.yml:

devices:
  test-server:
    type: test1
    os: test
    tacacs:
      username: admin
    passwords:
      tacacs: admin
    connections:
      defaults:
        class: unicon.Unicon
      cli:
        protocol: ssh
        ip: 1.1.1.1
        port: 2024
      rest:
        protocol: http
        ip: 1.1.1.1
        port: 8080
        username: admin
        password: admin
  RFS1:
    type: test
    os: test
    tacacs:
      username: admin
    passwords:
      tacacs: admin
    connections:
      defaults:
        class: unicon.Unicon
      cli:
        protocol: ssh
        ip: 1.1.1.1
        port: 2024
      rest:
        protocol: http
        ip: 4.4.4.4
        port: 8080
        username: admin
        password: admin
  RFS2:
    type: test
    os: test
    tacacs:
      username: admin
    passwords:
      tacacs: admin
    connections:
      defaults:
        class: unicon.Unicon
      cli:
        protocol: ssh
        ip: 1.1.1.1
        port: 2024
      rest:
        protocol: http
        ip: 6.6.6.6
        port: 8080
        username: admin
        password: admin

Here I need to search the IP which is under devices:/test-server:/connections:/cli:/ip: 1.1.1.1 with some new charcter like ip:10.10.10.10 using groovy script. I am using below code.

def myFile = new File("test.yml") 
def fileText = myFile.text
fileText = (fileText =~ /ip:1.1.1.1/).replaceFirst("ip:10.10.10.10")
myFile.write(fileText)

Here my issue is its replacing the required string in whole file where ip:1.1.1.1 is present but I need to replace under devices:/test-server:/connections:/cli:/ip: 1.1.1.1. Please help me to resolve this issue.


Solution

  • A better way to do this is to simply do YAML parsing, manipulating the object, and saving back to the file.

    Here's an example using Jackson:

    @Grab(group='com.fasterxml.jackson.dataformat', 
          module='jackson-dataformat-yaml', 
          version='2.12.2')
    
    def myFile = new File("test.yml")
    def om = new com.fasterxml.jackson.databind.ObjectMapper(
                 new com.fasterxml.jackson.dataformat.yaml.YAMLFactory());
    def value = om.readValue(myFile, Map)
    value['devices']['test-server']['connections']['cli']['ip'] = '10.10.10.10'
    

    That replaces the value in the in-memory object. You can then just save that back to a file, with something like:

    om.writeValue(myFile, value)