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.

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/'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.