I want to extract XML block surrounding search string
Ex: print XML block for string "myapp1-ear" surrounded by "<application> .. </application>"
Input XML:
If the awk script I suggested was too complicated for you, you could try this simple ed script:
#!/bin/ksh
strear='myapp1-ear'
ed -s xmlfile.xml <<EOF
g/<application-name>$strear<\/application-name>/?<application>?,/<\/application>/p
EOF
This will work with any shell that recognizes basic Bourne shell syntax (so you can use bash instead of ksh if you want to.
If I knew more details about your XML file tags, the BREs in the above script could probably be significantly simplified. With the limited information provided, these verbose BREs should accurately perform the requested operation as long as the opening <application> and closing </application> tags are on lines by themselves as shown in your sample data.
If you still don't like this, feel free to use your better ammo.
Don ed solution worked great.. I never used it, I need to understand how its working. syntax looks very close to sed . I wish I could use a single like sed for this.
Aia,, your solution worked when I removed prefix spaces with tag <application> . I tried below to allow spaces, its not working..
All those ^I is a tab. The indentation is a mix between normal spaces and tabs.
Your latest request "appears" to be to select from XML each line until </notify-list> and <application> and stop. That does not make much sense, since it would yield:
Hi, sed was based on ed ; ed came first. ed can do forwards and backwards searches; sed can't do backwards searches. The syntax for the ed g command is:
g/BRE/command
It tells ed to identify every line in the file that matches the basic regular expression BRE and for each line found, execute command on that line. And command in this case is:
?BRE1?,/BRE2/p
where p is the print command which takes zero, one, or two addresses to specify a range of lines to be printed. (No addresses prints the current line; one address prints the addressed line, and two addresses (separated by a comma) prints the lines from the 1st address up to and including the 2nd address.) The address specified by ?BRE1? searches for the line matching the basic regular expression BRE1 backwards from the current line and (as with sed ) /BRE2/ searches forwards from the current line for a line matching the basic regular expression BRE2 .
With your new sample input, the ed script I suggested should still print the lines you want. And, if you like to write less portable, 1-liners instead of code that will work with any POSIX-conforming shell, you can translate this to:
so I started doing something like this, but it is not working.
# This is to get initial generic XML block of text.
ed -s xmlfile.xml <<EOF
g/<notify-list>/?<deployment-request>?,<\/deployment-request>/p
q
EOF
# once above one works, I would like to append that with matched block of XML.
ed -s xmlfile.xml <<EOF
g/<notify-list>/?<deployment-request>?,<\/deployment-request>/p
g/<application-name>$strear<\/application-name>/?<application>?,/<\/application>/p
q
EOF
You're making it much more difficult than it needs to be. The ed commands needed to print the header and the trailer are identical to the sed commands you need to do the same thing. And, there is no need for three invocations of ed to get the output you want. Try:
#!/bin/ksh
strear='myapp1-ear'
ed -s xmlfile.xml <<EOF
1,/<\/notify-list>/p
g/<application-name>$strear<\/application-name>/?<application>?,/<\/application>/p
$ p
q
EOF
Note that the <space> before the p on the next to the last line in the ed script is not an accident and must not be removed. (If you don't understand why, ask.)
But, the output you say you want in post #12 does not match the spacing in your latest update to your input now shown in post #1. The code above preserves the blanks (spaces in the first few lines and tabs in the last few lines) found in your input file in the output it produces:
The function isn't throwing away line breaks. The shell is throwing away the line breaks in your echo statement because you didn't quote the expansion of the variable that was assigned the output from the function. Change:
echo $strXML
to:
echo "$strXML"
or, more safely:
printf '%s\n' "$strXML"
No, this will not preserve line breaks any more than the earlier attempt. You still have an unquoted expansion of a variable containing line breaks.
And, as you have found, you can't combine ed statements on a single line using semi-colon as a command separator.
should work. The first form is more portable and will work on any shell that performs POSIX-standard command substitutions and variable expansions.
The last form only works with recent versions of bash , ksh , and a few other shells supporting the <<< string redirection operator extension to the standards.
I will go with function. searching for ed related info on google has very little.
Looks like you are the last remaining expert,, I loved what it can do.