Search and Replace within XML tag via sed over multiple lines - sed

i want to change the value of a specific XML tag property.
There are many questions about how to handle sed, but the problem here is the newline within the tag.
I want to change the value after name= and it must be searched in the <package ... > tag
XMLStarlet is not an option.
Coverage.xml
<package branch-rate="0.031746031746" complexity="0.0"
line-rate="0.159420289855" name="include">
<classes>
<class branch-rate="0.0" complexity="0.0"
My best try so far:
sed -n '/<package/ {
:a
n
/<classes>/q
s/name=/xxxx/g
}' coverage.xml
Do you have an idea?
UPDATE 2: More of coverage.xml with approach of #RavinderSingh13
<package branch-rate="0.031746031746" complexity="0.0"
line-rate="0.159420289855" name="NEW_VALUE">
<classes>
<class branch-rate="0.0" complexity="0.0"
filename="NEW_VALUE"
name="NEW_VALUE">

If you are ok with awk, then as per your shown samples could you please try following once.(this will look only for package tag and its name value and for rest tags it will not do anything)
awk '/^>/{flag=""} /<package/{flag=1} flag && /name=/{sub(/name=.*\"/,"name=\"NEW_VALUE\"")} 1' Input_file
In case you want to save output into Input_file itself append > temp_file && mv temp_file Input_file to above code too.

I just did a little tweak using a for loop.
LINES=`awk '/<package /{print NR+1}' coverage.xml`
for i in ${LINES};
do
echo $i
sed -i ''"${i}"'s/name=.*/name="NEW_VALUE"/' coverage.xml;
done
The NR+1 helps to reach the second line in the package tag.

Related

Adding the xml tag after the specified string using SED

Planning to add the below content after the closing tab into the main.xml
Keeping the below xml tag information into the ADD.txt file.
<student>
<name>Bob</name>
<id>0111</id>
-----
</student>
Executing the following command: The information is adding above the tag </class>,
Planning to add the ADD.txt content after the tag </class>
sed -i '/</class>/e cat ADD.txt' main.xml

Using sed, delete from specific line until first match(not included)

I have some data looks like
1:Alice 2313
2:Desctop 456
3:Cook 111
4:.filename 50
...
...
100:Good 3
Dir num:10
File num:90
...
...
I want to delete all lines from specific line(ex. line 3) until the line "Dir num:" show up.
The idea output should be(according above example):
1:Alice 2313
2:Desctop 456
Dir num:10
File num:90
...
...
I have google several solutions likesed -i '/somestring/,$!d' file.
But these solutions are not suitable because of the specific line where deletion satarting.
How can I do this in 1 command without any tmp file?
Forgive my poor English, I'm not native English speaker.
You need to specify the address range from the specified line number (3) to the line matching the pattern (/Dir num/). However, it's not quite as simple as
sed '3,/Dir num/ d' file
because that will delete the "Dir num" line. Try this instead:
sed '3,/Dir num/ {/Dir num/! d}' file
That will, for the lines in the range, check that the line does not match the pattern: is the pattern is not matched, delete it.
Use the range: /pattern1/,/pattern2/ option of sed
$ sed -e '/2:Desctop 456/,/Dir num:10/{//!d}' inputFile
1:Alice 2313
2:Desctop 456
Dir num:10
File num:90
...
...

Search xml for a value using sed

I have a below xml file
<documents>
<document><title>some title1</title><abstract>Some abstract1</abstract></document>
<document><title>some title2</title><abstract>Some abstract2</abstract></document>
<document><title>some title3</title><abstract>Some abstract3</abstract></document>
<document><title>some title4</title><abstract>Some abstract4</abstract></document>
</documents>
I am trying to write a ksh script to fetch the abstract value based on title=title4
xmllint , xstartlet is not allowed in my machine (access issues)
I have tried with
sed -n '/abstract/{s/.*<abstract>//;s/<\/abstract.*//;p;}' connections.xml
How to modify this to search based on a title
Based on the example you have given:
sed -n '/title>.*title4<\/title>/{s#.*<abstract>##;s#</abstract>.*##;p}' file
Will give you:
Some abstract4
grep approach:
grep -Poz '<title>.*?title4</title><abstract>\K[^<>]+(?=</abstract>)' connections.xml && echo ""
The output:
Some abstract4

Sed add text after match

I have a xmltv file that has the following style lines for program start/stop times
<programme start="20150914003000" stop="20150914020000" channel="Noor TV">
I want to add +0000 to the end of the start/stop time like the following
<programme start="20150914003000 +0000" stop="20150914020000 +0000" channel="Noor TV">
I am using windows sed and got this far
sed -r "/<programme start=\"/ s/^([0-9]{14})/\1 +0000/g" < "xml.xml" > "xml2.xml"
its giving me sed cant read >: invalid argument
in the dos windows I can see its adding the +0000 but not writing the new file
I know its something dumb but I just cant figure it out.
thks.
Try this
sed -r "/<programme start=/ s/^([0-9]{14})/\1 +0000/g" "xml.xml" > "xml2.xml"
or (posix version)
sed "/<programme start=/ s/^([0-9]\{14\})/\1 +0000/g" "xml.xml" > "xml2.xml"
$cat xml.xml
<programme start="20150914003000" stop="20150914020000" channel="Noor TV">
$sed -r 's/start="([0-9]{14})" stop="([0-9]{14})"/start="\1 +0000" stop="\2 +0000"/' xml.xml >xml2.xml
$cat xml2.xml
<programme start="20150914003000 +0000" stop="20150914020000 +0000" channel="Noor TV">
had tried it by online linux
The first < needs a backslash, not a forward slash.
sed -r "\<programme start=\"/ s/^([0-9]{14})/\1 +0000/g" < "xml.xml" > "xml2.xml"

How do I create rules for CPPCHECK

I have created the following rule file for cpp check:
<?xml version="1.0"?>
<rule version="1">
<pattern>virtual .* \( .*dword .* \)</pattern>
<message>
<id>virtual function</id>
<summary>Possible error </summary>
</message>
</rule>
This rule is detecting only the first matching item in the code
what will be the problem.
I am a Cppcheck developer.
I am not sure .. but if pcre is greedy then the match will contain all code from the first virtual function, until the very last ')' in your code.
don't use .* , maybe [^)]* works better.
If you use --rule on the command line you can see what it matches.