I am trying to replace some html links such that they open in a new tab (Except links that point to the same page).

Here is a dummy html page to illustrate my issue. I call it test.html.

This is the <a href="https://www.google.com/">Google link</a>

And these are <a href="https://twitter.com/">Twitter link</a> and <a href="https://www.instagram.com/">Instagram link</a>.

I am using this code to find and replace links with some addition.

sed -E 's/(<a href="[^#]+[-a-zA-Z0-9@:%._\+~#=/?&]+")(>)/\1 target="_blank">/g' test.html

The result looks like this:

This is the <a href="https://www.google.com/" target="_blank">Google link</a>

And these are <a href="https://twitter.com/">Twitter link</a> and <a href="https://www.instagram.com/" target="_blank">Instagram link</a>.

Note the addition of target="_blank". It works as expected, except when there are multiple matches. In case of multiple matches per line, only the rightmost one is replaced. It seems to be detecting the whole line as a block.

Looking into this a bit, I found a suggestion to add a negation to split the detection blocks. So I added a negation for closing tag > like ^> so the code looks like

sed -E 's/(<a href="[^#]+[-a-zA-Z0-9@:%._\+~#=/?&^>]+")(>)/\1 target="_blank">/g' test.html

But this doesn't seem to do anything. Perhaps, I am doing this wrong.

Running/testing now on sed 4.7. Intended to be run on sed 4.4.

  • 1
    Do not use sed to edit html. Better to use some proper html parser, e.g. python's BeautifulSoup module.
    – pLumo
    Apr 29 at 14:33
  • Yes, I agree that this is not a robust solution. It's just intended as a quick temporary fix while something more complex is being worked on.
    – rmf
    Apr 29 at 14:52
  • I love the optimism of believing that a quick-and-dirty fix will actually get replaced with a robust, correct solution any time before the Q&D hack breaks (which will almost certainly be at the worst possible moment, in the worst possible way).
    – cas
    Apr 29 at 15:06

The expression [^#]+ matches everything from the first href to the end of the second. If you want to avoid only links starting with #, remove the +.

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.