Easiest method for removing html/xml <tags> from single-line output

html, sed, xml

Solution

Try this for your sed expression:

sed 's/<.*>\(.*\)<\/.*>/\1/'

Quick breakdown of the expression:

<.*>   - Match the first tag
\(.*\) - Match and save the text between the tags   
<\/.*> - Match the end tag making sure to escape the / character  
\1     - Output the result of the first saved match 
       -   (the text that is matched between \( and \))

More about back-references

A question came up in the comments that should probably be addressed for completeness.

The `\(` and `\)` are Sed's back-reference markers. They save a portion of the matched expression for use later.

For example, if we have an input string:

This has (parens) in it. In addition we can use parenslike thisparens using back-references.

We develop an expression:

sed s/.*(\(.*\)).*\1\\(.*\)\1.*/\1 \2/

Which gives us:

parens like this

How the heck did that work? Let's break down the expression to find out.

Expression breakdown:

sed s/ - This is the opening tag to a sed expression.
.*     - Match any character to start (as well as nothing).
(      - Match a literal left parenthesis character.
\(.*\) - Match any character and save as a back-reference. In this case it will match anything between the first open and last close parenthesis in the expression.
)      - Match a literal right parenthesis character.
.*     - Same as above.
\1     - Match the first saved back-reference. In the case of our sample this is filled in with `parens`
\(.*\) - Same as above.
\1     - Same as above.
/      - End of the match expression. Signals transition to the output expression.
\1 \2  - Print our two back-references.
/      - End of output expression.

As we can see, the back-reference taken from between the parenthesis (`(` and `)`) was substituted back into the matching expression to be able to match the string `parens`.

Problem

I have output from grep I'm trying to clean up that looks like: ``` <words>Http://www.path.com/words</words> ``` I've tried using... ``` sed 's/<.*>//' ``` ...to remove the tags, but that just destroys the entire line. I'm not sure why that's happening, since every '<' is closed with a '>' before it gets to the content. What is the easiest way to do this? Thanks!

Original source