1

Take this simple example:

echo "20150310 21:12:01.846338::: <?xml version="1.0"?><Haystack><Event " \
| sed 's/^\(.\{24\}\)::: \(<?xml.*><Haystack\|Foo\)>\(.*\)/\2 ts=\"\1\">\3/'

Will return:

<?xml version=1.0?><Haystack ts="20150310 21:12:01.846338"><Event

Essentially I want to take the first 24 chars of the line, insert them as a xml attribute of the root element and replace the rest of the xml. This works.

But if I transpose the Haystack\|Foo to Foo\|Haystack it simply returns the original string, finding no match. I actually have about 7 root elements to look for.

But the \| is supposed to be how you enter multiple words to match against such as in:

echo "foo" | sed 's/foo\|bar/nobar/'

So how do I get the () reference match to work the same way as above?

I'm using Fedora Linux, sed version 4.2.2.

Also, if someone can suggest a more efficient regex, I would be most grateful. This is part of a much larger problem set with about 7 root XML expressions I'm looking for and need it to run as fast as possible.

1 Answer 1

3

Your expression is telling sed to match either <?xml.*><Haystack or Foo. The Regex engine uses the capturing parenthesis to tell how far left or right to extend the or operator. (If you used a PCRE engine, then you could use non-capturing parenthesis.)


Original, problematic code:

echo "20150310 21:12:01.846338::: <?xml version="1.0"?><Haystack><Event " \
| sed 's/^\(.\{24\}\)::: \(<?xml.*><Haystack\|Foo\)>\(.*\)/\2 ts=\"\1\">\3/'

Fixed code:

echo "20150310 21:12:01.846338::: <?xml version="1.0"?><Haystack><Event " \
| sed 's/^\(.\{24\}\)::: \(<?xml.*>\)<\(Haystack\|Foo\)>\(.*\)/\2<\3 ts=\"\1\">\4/'
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .