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