Home > database >  Replace random generated resource name in the xml list in Bash to be useful Jenkins grrovy pipeline
Replace random generated resource name in the xml list in Bash to be useful Jenkins grrovy pipeline

Time:08-29

I have an xml file to find and replace a line where there is url which is linked to where the Resource name = "java/RulesPlugin"

The issue is that sometimes the <Resource name="java/RulesPlugin" might be out of sequence and not in the first line. I was only able to find the example.co.uk if the Resource name = "java/RulesPlugin" is first in the list but I need to be able to filter where the url is with <Resource name="java/RulesPlugin" no matter the location or sequence in that file.

script :

grep -oPm1 '(?<=url="jdbc:postgresql://)[^<] ' <  test.xml | sed -r 's/^.{0}//' | sed 's/^[[:space:]]*//' |   cut -d: -f1
varurl=`grep -oPm1 '(?<=url="jdbc:postgresql://)[^<] ' <  test.xml | sed -r 's/^.{0}//' | sed 's/^[[:space:]]*//' |   cut -d: -f1`
echo "${varurl}"        
sed -i -e "0,/$varurl/ s/$varurl/newstring-replace.co.uk/g" test.xml

If the xml content with <Resource name="java/RulesPlugin" is not the first in the list but is down in the middle randomly. How can I use bash to get this same result?

 <?xml version="1.0"?>
    
    <Context>
    <Resource name="java/RulesPlugin"
          auth="Container"
          type="javax.sql.DataSource"
          driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://example.co.uk:5000/sandbox"
          user="xxxx"
          token="xxxxx"
          maxActive="100" 
          maxIdle="30" 
          maxWait="10000"
    
      />
      
      <Resource name="java/Reports"
          auth="Container"
          type="javax.sql.DataSource"
          driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://example.co.uk:5000/sandbox"
          user="xxxx"
          token="xxxxx"
          
     />
      <Resource name="java/Balancer"
          auth="Container"
          type="javax.sql.DataSource"
          driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://example.co.uk:5000/sandbox"
          user="xxxx"
          token="xxxxx"
    
     />

UPDATE: Thanks for all the answers, some do work on the local unix, but I really need xml tool to work with Jenkins pipeline.

CodePudding user response:

It can be done with xmllint (present on most distros) as below. New value must be set on url variable

url="jdbc://asdasdas" echo -e "cd /Context/Resource[@name='java/RulesPlugin']/@url\nset $url\nsave\nbye") |  xmllint --shell tmp.xml
/ > cd /Context/Resource[@name='java/RulesPlugin']/@url
url > set jdbc://asdasdas
url > save
url > bye

As the output shows, 4 commands were pass to xmllint --shell

/ > cd /Context/Resource[@name='java/RulesPlugin']/@url
url > set jdbc://asdasdas
url > save
url > bye

Alternatively and assuming XML format is in the provided format regardless of attributes order, it could be done with awk as

url='url="jdbc:postgresql://example.com:7777/sandbox"'
gawk -v url="$url" '
    BEGIN{RS="[/]>\n"; FS="\n"; OFS="\n"}
    {
        if (NR==1 && $0 ~ /java[/]RulesPlugin/){
            for(i=1; i<=NF; i  ) {
                if($i ~ /url=/) $i = url
            }
            print $0 "/>"
        } else {
            print $0 "/>"
        }
}' tmp.xml

And with sed as

tr -d '\n' < tmp.xml | sed -re 's/^(.*Resource name="java\/RulesPlugin" [^>]   url=")([^=" ] )(" [^>]  *[/]>.*)/\1NEWURL\3/'

CodePudding user response:

This might work for you though parsing xml with sed is not a robust method.

sed '/Resource name="java\/RulesPlugin"/,/\/>[[:blank:]]*$/{
     /\(.*url="jdbc:postgresql:\/\/\)[^:/]*/s//\1newstring-replace.co.uk/
}' test.xml

CodePudding user response:

Please don't use inappropriate tools to parse XML! An XML-parser like would be more suited:

$ xidel -s test.xml -e '
  x:replace-nodes(
    Context/Resource[@name="java/RulesPlugin"]/@url,
    attribute url {"newstring-replace.co.uk"}
  )
' --output-format=xml --output-node-indent
  • Related