Home > Net >  Replace random generated resource name in the xml list in Bash
Replace random generated resource name in the xml list in Bash

Time:08-27

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"
    
     />

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
  • Related